HEX
Server: Apache/2.2.34 (Unix) mod_fastcgi/mod_fastcgi-SNAP-0910052141
System: Linux Kou-Etsu-Dou 4.4.59+ #25556 SMP PREEMPT Thu Mar 4 18:03:46 CST 2021 x86_64
User: hosam (1026)
PHP: 7.2.29
Disabled: NONE
Upload Files
File: /volume1/web/wordpress/wp-content/plugins/lingotek-translation/include/api.php
<?php

require_once('http.php');

/**
 * manages communication with Lingotek TMS
 * uses Lingotek API V5
 *
 * @since 0.1
 */
class Lingotek_API extends Lingotek_HTTP {
	protected $base_url;
	protected $api_url;
	protected $client_id;
	private $auth_temp;

	const PRODUCTION_URL = "https://myaccount.lingotek.com";
	const CLIENT_ID = "780966c9-f9c8-4691-96e2-c0aaf47f62ff";// Lingotek App ID


	private $bridge_url = '';

	/**
	 * constructor
	 *
	 * @since 0.1
	 */
	public function __construct() {
		$base_url = get_option('lingotek_base_url');
		$this->base_url = $base_url ? $base_url : self::PRODUCTION_URL;
		$this->api_url = $this->base_url.'/api';
		$this->client_id = self::CLIENT_ID;
		$token_details = get_option('lingotek_token');
		$this->headers['Authorization'] = 'bearer ' . $token_details['access_token'];
		$this->defaults = get_option('lingotek_defaults');

		$this->bridge_url = BRIDGE_URL . '/api/v2/transaction/translation/';
	}

	public function get_token_details($access_token) {
		$url = $this->base_url . "/auth/oauth2/access_token_info?access_token=" . $access_token;
		Lingotek_Logger::debug( "GET" , array( "url" => $url, "method" => __METHOD__));
		$response = wp_remote_get($url);
		$response_code = wp_remote_retrieve_response_code($response);

		if ($response_code == 200) {
			$response_body = json_decode(wp_remote_retrieve_body($response));
			$token_details = $response_body;
		}
		else {
			$token_details = FALSE;
		}
		$this->log_error_on_response_failure($response, "GetTokenDetails: Error occured");
		return $token_details;
	}

	public function get_api_url() {
		return $this->api_url;
	}

	/**
	 * updates the projet callback
	 *
	 * @since 0.2
	 *
	 * @param string $project_id
	 */
	public function update_callback_url($project_id) {
		$args = array('callback_url' => add_query_arg('lingotek', 1, site_url()));
		$response = $this->patch($this->api_url . '/project/' . $project_id, $args);
		Lingotek_Logger::info('Request to update callback url', array('project_id' => $project_id));
		$this->log_error_on_response_failure($response, 'UpdateCallbackUrl: Error occured', array('project_id' => $project_id));
		return !is_wp_error($response) && 204 == wp_remote_retrieve_response_code($response);
	}

  /**
	 * creates a new project
	 *
	 * @since 0.2
	 *
	 * @param string $title
	 */
	public function create_project($title, $community_id) {
		$args = array(
			'title' => $title,
			'community_id' => $community_id,
			'workflow_id' => $this->get_workflow_id(),
			'callback_url' => add_query_arg('lingotek', 1, site_url()),
		);

		$response = $this->post($this->api_url . '/project', $args);
		if(!is_wp_error($response) && 201 == wp_remote_retrieve_response_code($response)) {
			$new_id = json_decode(wp_remote_retrieve_body($response));
			Lingotek_Logger::info('Project created', array('id' => $new_id->properties->id, 'title' => $title));
			return $new_id->properties->id;
		}
		
		$this->log_error_on_response_failure($response, 'CreateProject: Error occured', array('title' => $title, 'community_id' => $community_id));
		return false;
	}

	/**
	 * uploads a document
	 *
	 * @since 0.1
	 *
	 * @param array $args expects array with title, content and locale_code
	 * @returns bool|string document_id, false if something got wrong
	 */
	public function upload_document($args, $wp_id = null) {
		$args = wp_parse_args($args, array('format' => 'JSON', 'project_id' => $this->defaults['project_id'], 'workflow_id' => $this->get_workflow_id()));
		$this->format_as_multipart($args);
		$response = $this->post($this->api_url . '/document', $args);

		$this->update_lingotek_error_option($response, $wp_id, 'upload_document', sprintf(__('There was an error uploading WordPress item %1$s', 'lingotek-translation'), $wp_id));

		if (!is_wp_error($response) && 202 == wp_remote_retrieve_response_code($response)) {
			$b = json_decode(wp_remote_retrieve_body($response));
			Lingotek_Logger::info('Document uploaded', array('document_id' => $b->properties->id, 'wp_id' => $wp_id));
			return $b->properties->id;
		}
		return false;
	}

	/**
	 * modifies a document
	 *
	 * @since 0.1
	 *
	 * @param string $id document id
	 * @param array $args expects array with content
	 * @return bool false if something got wrong
	 */
	public function patch_document($id, $args, $wp_id = null) {
		$args = wp_parse_args($args, array('format' => 'JSON'));
		$this->format_as_multipart($args);
		$response = $this->patch($this->api_url . '/document/' . $id, $args);

		$this->update_lingotek_error_option($response, $wp_id, 'patch_document', sprintf(__('There was an error updating WordPress item %1$s', 'lingotek-translation'), $wp_id), array('document_id' => $id));
		
		$is_success = !is_wp_error($response) && 202 == wp_remote_retrieve_response_code($response);
		if ($is_success) { Lingotek_Logger::info('Document updated', array('document_id' => $id, 'wp_id' => $wp_id)); }

		return $is_success;
	}

	/**
	 * deletes a document
	 *
	 * @since 0.1
	 *
	 * @param string $id document id
	 */
	public function delete_document($id, $wp_id = null) {
		$response = $this->delete($this->api_url . '/document/' . $id);

		if ($wp_id) {
			$arr = get_option('lingotek_log_errors');
			if (isset($arr[$wp_id])) {
				unset($arr[$wp_id]);
				update_option('lingotek_log_errors', $arr);
			}
		}

		$this->log_error_on_response_failure($response, 'DeleteDocument: Error occured', array('id' => $id, 'wordpress_id' => $wp_id));
		$is_success = !is_wp_error($response) && (204 == wp_remote_retrieve_response_code($response) || 202 == wp_remote_retrieve_response_code($response));
		if ($is_success) { Lingotek_Logger::info('Document deleted', array('document_id' => $id, 'wp_id' => $wp_id)); }
		
		return $is_success;
	}


	/**
	 * get all documents ids
	 *
	 * @since 0.1
	 */
	public function get_document_ids($args = array()) {
		$response = $this->get(add_query_arg($args, $this->api_url . '/document'));
		$ids = array();

		if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
			$documents = json_decode(wp_remote_retrieve_body($response));
			foreach ($documents->entities as $doc) {
				$ids[] = $doc->properties->id;
			}
		}

		$this->log_error_on_response_failure($response, 'GetDocumentIds: Error occured');
		return $ids;
	}

	public function get_document_count($args = array()) {
		$response = $this->get(add_query_arg($args, $this->api_url . '/document'));
		$docs = array();

		if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
			$response = json_decode(wp_remote_retrieve_body($response));
			return $response->properties->total;
		}

		$this->log_error_on_response_failure($response, 'GetDocumentCount: Error occured');
		return null;
	}

	/**
	 * get all documents
	 *
	 * @since 0.1
	 */
	public function get_documents($args = array()) {
		$response = $this->get(add_query_arg($args, $this->api_url . '/document'));
		$docs = array();

		if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
			$documents = json_decode(wp_remote_retrieve_body($response));
			foreach ($documents->entities as $doc) {
				$docs[] = $doc;
			}
		}

		$this->log_error_on_response_failure($response, 'GetDocuments: Error occured');
		return $docs;
	}

	/**
	 * get document by id
	 *
	 * @since 0.1
	 */
	public function get_document($doc_id) {
		$response = $this->get($this->api_url . '/document/' . $doc_id);

		if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
			$document = json_decode(wp_remote_retrieve_body($response));
		}

		$this->log_error_on_response_failure($response, 'GetDocument: Error occured');
		return $document;
	}

	public function get_document_status($doc_id)
	{
		$imported = FALSE;
		$response = $this->get($this->api_url . '/document/' . $doc_id . '/status');

		if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
			$imported = TRUE;
		}

		$this->log_error_on_response_failure($response, 'GetDocumentStatus: Error occured', array('document_id' => $doc_id));
		return $imported;
	}


	/**
	 * get specific document content
	 *
	 * @since 0.1
	 *
	 * @param string $id document id
	 * @return string
	 */
	public function get_document_content($doc_id) {
		$response = $this->get($this->api_url . '/document/' . $doc_id . '/content');

		if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
			$content = wp_remote_retrieve_body( $response );
		}

		$this->log_error_on_response_failure($response, 'GetDocumentContent: Error occured', array('document_id' => $doc_id));
		return $content;
	}

	/**
	 * check translations status of a specific locale for a document
	 *
	 * @since 0.1
	 *
	 * @param string $doc_id document id
	 * @param string $locale locale
	 * @return int with locale percent_complete
	 */
	public function get_translation_status($doc_id, $locale) {
		$locale = Lingotek::map_to_lingotek_locale($locale);
		$status = -1;
		$response = $this->get($this->api_url . '/document/' . $doc_id . '/translation/' . $locale);
		if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
			$b = json_decode(wp_remote_retrieve_body($response));
			$status = $b->properties->percent_complete;
		}

		return $status;
	}

	/**
	 * check translations status of a document
	 *
	 * @since 0.1
	 *
	 * @param string $id document id
	 * @return array with locale as key and status as value
	 */
	public function get_translations_status($doc_id, $wp_id = null) {
		$response = $this->get($this->api_url . '/document/' . $doc_id . '/translation');
		if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
			$b = json_decode(wp_remote_retrieve_body($response));
			foreach ($b->entities as $e) {
				$translations[$e->properties->locale_code] = $e->properties->percent_complete;
			}
		}

		Lingotek_Logger::info('Translation status requested', array('document_id' => $doc_id, 'wp_id' => $wp_id, 'translations' => isset($translations) ? $translations : '' ));
		
		$this->update_lingotek_error_option(
			$response, 
			$wp_id, 
			'get_translations_status', 
			sprintf(__('There was an error updating the translations status for WordPress item %1$s', 'lingotek-translation'), $wp_id), 
			array('document_id'=>$doc_id));

		return empty($translations) ? array() : $translations;
	}


	public function get_language_mappings()
	{
		$url = 'https://gmc.lingotek.com/v1/locales';
		$response = $this->get($url);
		return json_decode(wp_remote_retrieve_body($response),true);
	}

	/**
	* Makes an API call to bridge to get the estimated cost for translating a particular document professionally. 
	*
	* @param string $lingotek_auth the auth token to make an API call to bridge.
	* @param string $document_id the id of the specific document. 
	* @param string $locale the locale of the document being requested.
	*/
	public function get_cost_estimate($lingotek_auth, $document_id, $locale) {
		$this->start_bridge_call();

		$args = array(
			'document_id' => $document_id,
			'locale' => $locale
		);
		$response = $this->get($this->bridge_url . 'estimate', $args);

		$success = 200 === wp_remote_retrieve_response_code($response);

		$this->end_bridge_call();

		$this->log_error_on_response_failure($response, 'GetCostEstimate: Error occured', array('document_id' => $document_id, 'locale' => $locale));
		return array('success' => $success, 'data' => $this->get_response_body_from_bridge($response));
	}

	/**
	* Makes an API call to bridge request translation for a document using the professional workflow. 
	*
	* @param string $document_id the id of the specific document. 
	* @param string $locale the locale of the document being requested.
	* @param string $workflow_id the id used to process the document.
	*/
	public function request_professional_translation($document_id, $locale, $workflow_id) {
		$this->start_bridge_call();
		
		$args = array(
			'document_id' => $document_id,
			'locale' => $locale,
			'workflow_id' => $workflow_id,
		);
		$response = $this->post($this->bridge_url . 'request', $args);
		$success = 200 === wp_remote_retrieve_response_code($response);

		$this->end_bridge_call();

		if ($success) { Lingotek_Logger::info('Professional translation requested', array('document_id' => $document_id, 'locale' => $locale, 'wordflow_id' => $workflow_id)); }
		$this->log_error_on_response_failure($response, 'RequestProfessionalTranslation: Error occured', array('document_id' => $document_id, 'locale' => $locale, 'workflow_id' => $workflow_id));

		return array('success' => $success, 'data' => $this->get_response_body_from_bridge($response));
	}

	/**
	* Makes an API call to bridge request bulk translations for a document using the professional workflow. 
	*
	* @param string $document_id the id of the specific document. 
	* @param string $locale the locale of the document being requested.
	* @param string $workflow_id the id used to process the document.
	*/
	public function request_professional_translation_bulk($workflow_id, $translations, $total_estimate, $summary) {
		$this->start_bridge_call();
		
		$args = array(
			'workflow_id' => $workflow_id,
			'translations' => $translations,
			'total_estimate' => $total_estimate,
			'summary' => $summary
		);
		$response = $this->post($this->bridge_url . 'request/bulk', $args, 60);
		$success = 200 === wp_remote_retrieve_response_code($response);

		$this->end_bridge_call();

		if ($success) { Lingotek_Logger::info('Professional translation (bulk) requested', array('translations' => $translations, 'wordflow_id' => $workflow_id)); }
		$this->log_error_on_response_failure($response, 'RequestProfessionalTranslationBulk: Error occured', array('translations' => $translations, 'total_estimate' => $total_estimate, 'workflow_id' => $workflow_id));

		return array('data' => $this->get_response_body_from_bridge($response));
	}


	public function get_lingotek_terms_and_conditions() {
		$this->start_bridge_call();
		$response = $this->get(BRIDGE_URL . '/api/v2/transaction/terms/');
		$success = 200 === wp_remote_retrieve_response_code($response);
		$this->end_bridge_call();

		$this->log_error_on_response_failure($response, 'GetLingotekTermsAndConditions: Error occured');
		return array('success' => $success, 'data' => $this->get_response_body_from_bridge($response));
	}

	/**
	* Makes an API call to bridge to get the payment information about the user.
	*/
	public function get_user_payment_information() {
		$this->start_bridge_call();

		$response = $this->get(BRIDGE_URL . '/api/v2/transaction/payment');
		$success = 200 === wp_remote_retrieve_response_code($response);

		$this->end_bridge_call();

		$this->log_error_on_response_failure($response, "GetUserPaymentInformation: Error occured");
		return array('success' => $success, 'payment_info' => $this->get_response_body_from_bridge($response));
	}

	/**
	* Helper function to retrieve the response body from bridge.
	*
	* @param array $response the response from bridge.
	*/
	private function get_response_body_from_bridge($response)
	{
		$body = json_decode(wp_remote_retrieve_body($response),true);
		return isset($body) ? $body : wp_remote_retrieve_body($response);
	}

	/**
	 * requests a new translation of a document
	 *
	 * @since 0.1
	 *
	 * @param string $id document id
	 * @param string $locale Lingotek locale
	 * @param array $args optional arguments (only workflow_id at the moment)
	 * @return bool true if the request succeeded
	 */
	public function request_translation($id, $locale, $args = array(), $wp_id = null) {
		$locale = Lingotek::map_to_lingotek_locale($locale);
		$args = wp_parse_args($args, array('workflow_id' => $this->get_workflow_id()));
		$args = array_merge(array('locale_code' => $locale), $args);
		$response = $this->post($this->api_url . '/document/' . $id . '/translation', $args);

		if ($wp_id) {
			$arr = get_option('lingotek_log_errors');

			if (201 == wp_remote_retrieve_response_code($response)) {
				if (isset($arr[$wp_id])) {
					unset($arr[$wp_id]['wp_error']);
					unset($arr[$wp_id]['request_translation'][$locale]);
					if (empty($arr[$wp_id])){
						unset($arr[$wp_id]);
					}
				}
			}
			else if (is_wp_error($response)) {
				$arr[$wp_id]['wp_error'] = __('Make sure you have internet connectivity', 'lingotek-translation');
			}
			else if (400 == wp_remote_retrieve_response_code($response) || 404 == wp_remote_retrieve_response_code($response)) {
				$arr[$wp_id]['request_translation'][$locale] = sprintf(
					__('There was an error requesting translation %1$s for WordPress item %2$s', 'lingotek-translation'), $locale, $wp_id
				);
			}
			update_option('lingotek_log_errors', $arr);
		}

		return !is_wp_error($response) && 201 == wp_remote_retrieve_response_code($response);
	}

	/**
	 * get a translation
	 *
	 * @since 0.1
	 *
	 * @param string $id document id
	 * @param string $locale Lingotek locale
	 * @return string|bool the translation, false if there is none
	 */
	public function get_translation($doc_id, $locale, $wp_id = null) {
		$locale = Lingotek::map_to_lingotek_locale($locale);

		$response = $this->get(add_query_arg(array('locale_code' => $locale, 'auto_format' => 'true') , $this->api_url . '/document/' . $doc_id . '/content'));

		if ($wp_id) {
			$arr = get_option('lingotek_log_errors');

			if (200 == wp_remote_retrieve_response_code($response)) {
				if (isset($arr[$wp_id])) {
					unset($arr[$wp_id]['wp_error']);
					unset($arr[$wp_id]['get_translation'][$locale]);
					if (empty($arr[$wp_id])) {
						unset($arr[$wp_id]);
					}
				}
			}
			else if (is_wp_error($response)) {
				$arr[$wp_id]['wp_error'] = __('Make sure you have internet connectivity', 'lingotek-translation');
			}
			else if (400 == wp_remote_retrieve_response_code($response) || 404 == wp_remote_retrieve_response_code($response)) {
				$arr[$wp_id]['get_translation'][$locale] = sprintf(
					__('There was an error downloading translation %1$s for WordPress item %2$s'), $locale, $wp_id
				);
			}
			update_option('lingotek_log_errors', $arr);
		}

		return !is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response) ? wp_remote_retrieve_body($response) : false;
	}

	/**
	 * deletes a translation
	 *
	 * @since 0.1
	 *
	 * @param string $id document id
	 * @param string $locale Lingotek locale
	 */
	public function delete_translation($id, $locale, $wp_id = null) {
		$response = $this->delete($this->api_url . '/document/' . $id . '/translation/' . $locale);

		if ($wp_id) {
			$arr = get_option('lingotek_log_errors');
			if (isset($arr[$wp_id])) {
				unset($arr[$wp_id]);
				update_option('lingotek_log_errors', $arr);
			}
		}
		// FIXME send a response
	}

	/**
	 * get connect account url
	 *
	 * @param string $redirect_uri the location where to redirect to after account has been connected
	 * @return string the complete url for the connect account link
	 */
	public function get_connect_url($redirect_uri, $env = NULL) {
		$base_url = $this->base_url;
		$client_id = $this->client_id;
		if(!is_null($env)){
			$base_url = self::PRODUCTION_URL;
		}
		return $base_url . "/auth/authorize.html?client_id=" . $client_id . "&redirect_uri=" . urlencode($redirect_uri) . "&response_type=token";
	}

	public function get_new_url($redirect_uri) {
		$base_url = self::PRODUCTION_URL;
		$client_id = $this->client_id;
		return $base_url . "/lingopoint/portal/requestAccount.action?client_id=" . $client_id . "&app=" . urlencode($redirect_uri) . "&response_type=token";

	}

	public function get_communities() {
		$response = $this->get(add_query_arg(array('limit' => 1000), $this->api_url . '/community'));
		return !is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response) ? json_decode(wp_remote_retrieve_body($response)) : false;
	}

	public function get_projects($community_id) {
		$response = $this->get(add_query_arg(array('community_id' => $community_id, 'limit' => 1000), $this->api_url . '/project'));
		if (wp_remote_retrieve_response_code($response) == 204) {
			return array();// there are currently no projects
		}
		return !is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response) ? json_decode(wp_remote_retrieve_body($response)) : false;
	}

	public function get_vaults($community_id) {
		$response = $this->get(add_query_arg(array('community_id' => $community_id, 'limit' => 1000), $this->api_url . '/vault'));
		return !is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response) ? json_decode(wp_remote_retrieve_body($response)) : false;
	}

	public function get_workflows($community_id) {
		$response = $this->get(add_query_arg(array('community_id' => $community_id, 'limit' => 1000), $this->api_url . '/workflow'));
		return !is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response) ? json_decode(wp_remote_retrieve_body($response)) : false;
	}

	public function get_filters() {
		$response = $this->get(add_query_arg(array('limit' => 1000), $this->api_url . '/filter'));
		return !is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response) ? json_decode(wp_remote_retrieve_body($response)) : false;
	}

	public function upload_filter($name, $type, $content) {
		$args = array('name' => $name, 'type' => $type, 'content' => $content);
		$response = $this->post($this->api_url . '/filter', $args);
	}

	private function start_bridge_call() {
		$this->auth_temp = $this->headers['Authorization'];
		unset($this->headers['Authorization']);
		$option = get_option('lingotek_token');
		$this->headers['Authorization-Lingotek'] = $option['access_token'];
	}

	private function end_bridge_call() {
		unset($this->headers['Authorization-Lingotek']);
		$this->headers['Authorization'] = $this->auth_temp;
	}

	private function get_workflow_id() {
		return 'project-default' === $this->defaults['workflow_id'] ? null : $this->defaults['workflow_id'];
	}

	/**
	* Helper function to update lingotek errors as 'lingotek_log_errors' option in case of translation actions (get / request).
	*
	* @param $response the response from the action (wp_remote_*).
	* @param $wp_id id that represents the object in the WP world (post_id / term_id / etc)
	* @param $action the name of the action performed (for ex 'reqeust_translation')
	* @param $error_message the message to write in case the response indicates failure
	* @param $locale the locale the translation action was performed on
	* @param $extra_data (optional) array of key/value pairs that will be sent as part of the error
	*/
	private function update_lingotek_error_option_for_translation($response, $wp_id, $action, $error_message, $locale, $extra_data = array()){
		if ($wp_id) {
			$arr = get_option('lingotek_log_errors');
			$response_message_code = wp_remote_retrieve_response_code($response);
			if (200 == $response_message_code || 201 == $response_message_code) {
				if (isset($arr[$wp_id])) {
					unset($arr[$wp_id]['wp_error']);
					unset($arr[$wp_id][$action][$locale]);
					if (empty($arr[$wp_id])) {
						unset($arr[$wp_id]);
					}
				}
			}
			else if (is_wp_error($response)) {
				$arr[$wp_id]['wp_error'] = __('Make sure you have internet connectivity', 'lingotek-translation');
				Lingotek_Logger::error($action.": Wordpress error occured, please make sure you have internet connectivity", array_merge(array('http_status'=>$response_message_code, 'wordpress_id'=>$wp_id), $extra_data));
			}
			else if (400 == $response_message_code || 404 == $response_message_code) {
				$arr[$wp_id][$action][$locale] = $error_message;
				Lingotek_Logger::error($action.": Error occured", array_merge(array('response_message_code'=>$response_message_code, 'wordpress_id'=>$wp_id, 'response_message'=>$this->get_error_message_from_response($response)), $extra_data));
			}
			update_option('lingotek_log_errors', $arr);
		}
	}

	/**
	* Helper function to update lingotek errors as 'lingotek_log_errors' option.
	*
	* @param $response the response from the action (wp_remote_*).
	* @param $wp_id id that represents the object in the WP world (post_id / term_id / etc)
	* @param $action the name of the action performed (for ex 'reqeust_translation')
	* @param $error_message the message to write in case the response indicates failure
	* @param $extra_data (optional) array of key/value pairs that will be sent as part of the error
	*/
	private function update_lingotek_error_option($response, $wp_id, $action, $error_message, $extra_data = array()){
		if ($wp_id){
			$arr = get_option('lingotek_log_errors');
			$response_message_code = wp_remote_retrieve_response_code($response);

			if (200 == $response_message_code || 202 == $response_message_code) {
				if (isset($arr[$wp_id])) {
					unset($arr[$wp_id]);
				}
			}
			else if (is_wp_error($response)) {
				$arr[$wp_id]['wp_error'] = __('Make sure you have internet connectivity', 'lingotek-translation');
				Lingotek_Logger::error($action.": Wordpress error occured, please make sure you have internet connectivity", array_merge(array('http_status'=>$response_message_code, 'wordpress_id'=>$wp_id), $extra_data));
			}
			else if (400 == $response_message_code || 404 == $response_message_code) {
				$arr[$wp_id][$action] = $error_message;
				Lingotek_Logger::error($action.": Error occured", array_merge(array('http_status'=>$response_message_code, 'wordpress_id'=>$wp_id, 'response_message'=>$this->get_error_message_from_response($response)), $extra_data));
			}
			update_option('lingotek_log_errors', $arr);
		}
	}

	/**
	* Helper function to send error log entry to Lingotek_Logger in case the response indicates failure.
	* Failure response has http status different than 200/201/202/204 and is not wp_error response
	*
	* @param $response the response from the action (wp_remote_*).
	* @param $error_message the message to write in case the response indicates failure
	* @param $extra_data (optional) array of key/value pairs that will be sent as part of the error
	*/
	private function log_error_on_response_failure($response, $error_message, $extra_data = array()){
		$http_code = wp_remote_retrieve_response_code($response);
		$success = 200 === $http_code || 201 === $http_code || 202 === $http_code || 204 === $http_code;
		if (!$success || is_wp_error($response)) Lingotek_Logger::error($error_message, array_merge(array('http_status'=>$http_code, $extra_data)));
	}

	private function get_error_message_from_response($response){
		$responseBody = json_decode(wp_remote_retrieve_body($response));
		return property_exists($responseBody, "messages") && is_array($responseBody->messages) ? implode(" ",$responseBody->messages) : false;
	}
}