/**
  * WPML_TP_Logger constructor.
  *
  * @param WPML_Pro_Translation         $pro_translation
  * @param WPML_Jobs_Fetch_Log_Settings $fetch_log_settings
  * @param WPML_Jobs_Fetch_Log_Job      $fetch_log_job
  */
 public function __construct(&$pro_translation, &$fetch_log_settings, &$fetch_log_job)
 {
     $this->pro_translation =& $pro_translation;
     $this->fetch_log_settings =& $fetch_log_settings;
     $this->logger_helper =& $fetch_log_job;
     $wpml_wp_api = $this->pro_translation->get_wpml_wp_api();
     $this->log_utils = new WPML_Jobs_Fetch_Log_Utils($wpml_wp_api, $this->fetch_log_settings);
 }
 /**
  * @param TranslationProxy_Project $project
  *
  * @return array
  */
 function poll_for_translations($project)
 {
     /** @var WPML_String_Translation $WPML_String_Translation */
     global $sitepress, $WPML_String_Translation;
     $pending_jobs = $project->pending_jobs();
     $cancelled_jobs = $project->cancelled_jobs();
     $results = array_fill_keys(array('completed', 'cancelled', 'errors'), 0);
     $posts_need_sync = array();
     if ($pending_jobs) {
         foreach ($pending_jobs as $job) {
             $ret = $this->pro_translation->download_and_process_translation($job->id, $job->cms_id);
             if ($ret) {
                 $results['completed']++;
                 if ($job->cms_id) {
                     list(, $id_to_sync) = $this->cms_id_helper->parse_cms_id($job->cms_id);
                 } else {
                     $id_to_sync = $job->id;
                 }
                 $posts_need_sync[] = $id_to_sync;
             }
         }
     }
     if (!empty($cancelled_jobs)) {
         foreach ($cancelled_jobs as $job) {
             $ret = false;
             if ($job->cms_id != "") {
                 //we have a cms id for post translations
                 $ret = $this->pro_translation->cancel_translation($job->id, $job->cms_id);
                 $ret = $ret ? 1 : 0;
             } else {
                 //we only have an empty string here for string translations
                 if (isset($WPML_String_Translation)) {
                     $ret = isset($job->id) ? $WPML_String_Translation->cancel_remote_translation($job->id) : false;
                 }
             }
             if ($ret) {
                 $results['cancelled'] += $ret;
             }
         }
     }
     $sitepress->set_setting('last_picked_up', strtotime(current_time('mysql')));
     $sitepress->save_settings();
     $this->pro_translation->enqueue_project_errors($project);
     do_action('wpml_new_duplicated_terms', $posts_need_sync, false);
     return $results;
 }
 /**
  * @param $data
  *
  * @return array
  */
 public function poll_job($data)
 {
     $job = !empty($data['job_polled']) ? $data['job_polled'] : false;
     $results = array('completed' => empty($data['completed_jobs']) ? 0 : $data['completed_jobs'], 'cancelled' => empty($data['cancelled_jobs']) ? 0 : $data['cancelled_jobs'], 'errors' => empty($data['error_jobs']) ? array() : $data['error_jobs']);
     if ($job && in_array($job['job_state'], array('cancelled', 'translation_ready', 'delivered', 'waiting_translation'))) {
         $is_missing_in_db = !empty($job['cms_id']) && !$this->cms_id_helper->get_translation_id($job['cms_id']);
         $job_state = in_array($job['job_state'], array('delivered', 'waiting_translation'), true) && $is_missing_in_db ? 'translation_ready' : $job['job_state'];
         if ($job_state === 'translation_ready' || !$is_missing_in_db && $job_state === 'cancelled') {
             $res = $this->pro_translation->xmlrpc_updated_job_status_with_log(array($job['id'], $job['cms_id'], $job_state), true);
         } else {
             $res = 0;
         }
         if ($res === 1) {
             if ($job['job_state'] === 'translation_ready') {
                 $results['completed']++;
             } elseif ($job['job_state'] === 'cancelled') {
                 $results['cancelled']++;
             }
         } else {
             $results['errors'] = (array) $results['errors'];
             $results['errors'][] = $res;
         }
     }
     $errors = "";
     $status_cancelled = "";
     if (!empty($results['errors'])) {
         $status = __('Error', 'sitepress');
         $errors = join('<br />', array_filter((array) $results['errors']));
         $job_error = true;
     } else {
         $status = __('OK', 'sitepress');
         $job_error = false;
     }
     if ($results['completed'] == 1) {
         $status_completed = __('1 translation has been fetched from the translation service.', 'sitepress');
     } elseif ($results['completed'] > 1) {
         $status_completed = sprintf(__('%d translations have been fetched from the translation service.', 'sitepress'), $results['completed']);
     } else {
         $status_completed = '';
     }
     if ($results['cancelled']) {
         $status_cancelled = sprintf(__('%d translations have been marked as cancelled.', 'sitepress'), $results['cancelled']);
     }
     return array('job_error' => $job_error, 'status' => $status, 'errors' => $errors, 'completed' => $status_completed, 'cancelled' => $status_cancelled);
 }
 /**
  * Handle job update notifications from TP
  *
  * @param array $args
  * @param bool  $bypass_auth if true forces ignoring the signature check when used together with polling
  *
  * @throws InvalidArgumentException
  * @return int|string
  */
 function update_status($args, $bypass_auth = false)
 {
     if (!isset($args[0], $args[1], $args[2], $args[3])) {
         throw new InvalidArgumentException('This method requires an array of 4 input parameters!');
     }
     $this->last_translation_proxy_job_id = $args[0];
     $this->last_cms_id = $args[1];
     $this->last_status = $args[2];
     $this->last_signature = $args[3];
     if (!$bypass_auth && !$this->authenticate_request()) {
         return 'Wrong signature';
     }
     $job_data = array();
     $job_data['id'] = $this->last_translation_proxy_job_id;
     $job_data['cms_id'] = $this->last_cms_id;
     $job_data['job_state'] = $this->last_status;
     $job_data['source_language'] = false;
     $job_data['target_language'] = false;
     switch ($this->last_status) {
         case 'translation_ready':
             $ret = $this->pro_translation->download_and_process_translation($this->last_translation_proxy_job_id, $this->last_cms_id);
             break;
         case 'cancelled':
             $ret = $this->pro_translation->cancel_translation($this->last_translation_proxy_job_id, $this->last_cms_id);
             break;
         default:
             return "Not supported status: {$this->last_status}";
     }
     $this->last_job_data = $job_data;
     if ($this->pro_translation->errors) {
         $result = implode('', $this->pro_translation->errors);
     } elseif ((bool) $ret === true) {
         $result = self::CMS_SUCCESS;
     } else {
         $result = self::CMS_FAILED;
     }
     return $result;
 }
 public function register_string($context, $name, $value, $allow_empty_value = false)
 {
     $name = trim($name) ? $name : md5($value);
     /* cpt slugs - do not register them when scanning themes and plugins
      * if name starting from 'URL slug: '
      * and context is different from 'WordPress'
      */
     if (substr($name, 0, 10) === 'URL slug: ' && 'WordPress' !== $context) {
         return false;
     }
     list($domain, $context) = $this->key_by_name_and_context($name, $context);
     list($name, $context) = $this->truncate_name_and_context($name, $context);
     $res = $this->get_registered_string($domain, $context, $name);
     if ($res) {
         $string_id = $res['id'];
         /*
          * If Sticky Links plugin is active and set to change links in Strings,
          * we need to process $value and change links into sticky before comparing
          * with saved in DB $res->value.
          * Otherwise after every String Translation screen refresh status of this string
          * will be changed into 'needs update'
          */
         $alp_settings = get_option('alp_settings');
         if (!empty($alp_settings['sticky_links_strings']) && $alp_settings['sticky_links_strings'] && defined('WPML_STICKY_LINKS_VERSION')) {
             // sticky links plugin is active?
             require_once ICL_PLUGIN_PATH . '/inc/absolute-links/absolute-links.class.php';
             $absolute_links_object = new AbsoluteLinks();
             $alp_broken_links = array();
             $value = $absolute_links_object->_process_generic_text($value, $alp_broken_links);
         }
         $update_string = array();
         if ($value != $res['value']) {
             $update_string['value'] = $value;
         }
         if (!empty($update_string)) {
             $this->wpdb->update($this->wpdb->prefix . 'icl_strings', $update_string, array('id' => $string_id));
             $this->wpdb->update($this->wpdb->prefix . 'icl_string_translations', array('status' => ICL_TM_NEEDS_UPDATE), array('string_id' => $string_id));
             icl_update_string_status($string_id);
         }
     } else {
         $string_id = $this->save_string($value, $allow_empty_value, 'en', $domain, $context, $name);
     }
     global $WPML_Sticky_Links;
     if (defined('WPML_TM_PATH') && !empty($WPML_Sticky_Links) && $WPML_Sticky_Links->settings['sticky_links_strings']) {
         require_once WPML_TM_PATH . '/inc/translation-proxy/wpml-pro-translation.class.php';
         WPML_Pro_Translation::_content_make_links_sticky($string_id, 'string', false);
     }
     $this->name_cache[md5($domain . $name . $context)] = $value;
     return $string_id;
 }
 /**
  *
  * Handle job update notifications from TP
  *
  * @param array $args
  * @param bool  $bypass_auth if true forces ignoring the signature check when used together with polling
  *
  * @return int|string
  */
 function update_status($args, $bypass_auth = false)
 {
     if (!(isset($args[0]) && isset($args[1]) && isset($args[2]) && isset($args[3]))) {
         throw new InvalidArgumentException('This method requires an array of 4 input parameters!');
     }
     $translation_proxy_job_id = $args[0];
     $cms_id = $args[1];
     $status = $args[2];
     $signature = $args[3];
     if (!$bypass_auth && !$this->authenticate_request($translation_proxy_job_id, $cms_id, $status, $signature)) {
         return "Wrong signature";
     }
     switch ($status) {
         case "translation_ready":
             $ret = $this->pro_translation->download_and_process_translation($translation_proxy_job_id, $cms_id);
             break;
         case "cancelled":
             $ret = $this->pro_translation->cancel_translation($translation_proxy_job_id, $cms_id);
             break;
         default:
             return "Not supported status: {$status}";
     }
     return $this->pro_translation->errors ? join('', $this->pro_translation->errors) : ((bool) $ret === true ? self::CMS_SUCCESS : self::CMS_FAILED);
 }
 public function register_string($context, $name, $value, $allow_empty_value = false)
 {
     global $wpdb;
     /* cpt slugs - do not register them when scanning themes and plugins
      * if name starting from 'URL slug: '
      * and context is different from 'WordPress'
      */
     if (substr($name, 0, 10) === 'URL slug: ' && 'WordPress' !== $context) {
         return false;
     }
     // if the default language is not set up return without doing anything
     if (!icl_get_setting('existing_content_language_verified')) {
         return false;
     }
     $translation = $this->string_from_registered($name, $context);
     if ($translation === $value) {
         return false;
     }
     list($name, $context) = $this->truncate_name_and_context($name, $context);
     $language = $this->language;
     $query = $wpdb->prepare("SELECT id, value, status FROM {$wpdb->prefix}icl_strings WHERE context=%s AND name=%s", $context, $name);
     $res = $wpdb->get_row($query);
     if ($res) {
         $string_id = $res->id;
         /*
          * If Sticky Links plugin is active and set to change links in Strings,
          * we need to process $value and change links into sticky before comparing
          * with saved in DB $res->value.
          * Otherwise after every String Translation screen refresh status of this string
          * will be changed into 'needs update'
          */
         $alp_settings = get_option('alp_settings');
         if (!empty($alp_settings['sticky_links_strings']) && $alp_settings['sticky_links_strings'] && defined('WPML_STICKY_LINKS_VERSION')) {
             // sticky links plugin is active?
             require_once ICL_PLUGIN_PATH . '/inc/absolute-links/absolute-links.class.php';
             $absolute_links_object = new AbsoluteLinks();
             $alp_broken_links = array();
             $value = $absolute_links_object->_process_generic_text($value, $alp_broken_links);
         }
         $update_string = array();
         if ($value != $res->value) {
             $update_string['value'] = $value;
         }
         if (!empty($update_string)) {
             $wpdb->update($wpdb->prefix . 'icl_strings', $update_string, array('id' => $string_id));
             $wpdb->update($wpdb->prefix . 'icl_string_translations', array('status' => ICL_TM_NEEDS_UPDATE), array('string_id' => $string_id));
             icl_update_string_status($string_id);
         }
     } else {
         $string_id = $this->save_string($value, $allow_empty_value, $language, $context, $name);
     }
     global $WPML_Sticky_Links;
     if (defined('WPML_TM_PATH') && !empty($WPML_Sticky_Links) && $WPML_Sticky_Links->settings['sticky_links_strings']) {
         require_once WPML_TM_PATH . '/inc/translation-proxy/wpml-pro-translation.class.php';
         WPML_Pro_Translation::_content_make_links_sticky($string_id, 'string', false);
     }
     $this->name_cache[$name . $context] = $value;
     return $string_id;
 }
 public function register_string($context, $name, $value, $allow_empty_value = false, $source_lang = '')
 {
     global $WPML_Sticky_Links;
     $name = trim($name) ? $name : md5($value);
     /* cpt slugs - do not register them when scanning themes and plugins
      * if name starting from 'URL slug: '
      * and context is different from 'WordPress'
      */
     if (substr($name, 0, 10) === 'URL slug: ' && 'WordPress' !== $context) {
         return false;
     }
     list($domain, $context, $key) = $this->key_by_name_and_context($name, $context);
     list($name, $context) = $this->truncate_name_and_context($name, $context);
     if ($source_lang == '') {
         $lang_of_domain = new WPML_Language_Of_Domain($this->sitepress);
         $domain_lang = $lang_of_domain->get_language($domain);
         $source_lang = $domain_lang ? $domain_lang : (strpos($domain, 'admin_texts_') === 0 || $name === 'Tagline' || $name === 'Blog Title' ? $this->sitepress->get_user_admin_language(get_current_user_id()) : 'en');
         $source_lang = $source_lang ? $source_lang : 'en';
     }
     $res = $this->get_registered_string($domain, $context, $name);
     if ($res) {
         $string_id = $res['id'];
         /*
          * If Sticky Links plugin is active and set to change links in Strings,
          * we need to process $value and change links into sticky before comparing
          * with saved in DB $res->value.
          * Otherwise after every String Translation screen refresh status of this string
          * will be changed into 'needs update'
          */
         $alp_settings = get_option('alp_settings');
         if (!empty($alp_settings['sticky_links_strings']) && $alp_settings['sticky_links_strings'] && defined('WPML_STICKY_LINKS_VERSION')) {
             // sticky links plugin is active?
             require_once ICL_PLUGIN_PATH . '/inc/absolute-links/absolute-links.class.php';
             $absolute_links_object = new AbsoluteLinks();
             $alp_broken_links = array();
             $value = $absolute_links_object->_process_generic_text($value, $alp_broken_links);
         }
         $update_string = array();
         if ($value != $res['value']) {
             $update_string['value'] = $value;
         }
         $existing_lang = $this->string_factory->find_by_id($res['id'])->get_language();
         if (!empty($update_string)) {
             if ($existing_lang == $source_lang) {
                 $this->wpdb->update($this->wpdb->prefix . 'icl_strings', $update_string, array('id' => $string_id));
                 $this->wpdb->update($this->wpdb->prefix . 'icl_string_translations', array('status' => ICL_TM_NEEDS_UPDATE), array('string_id' => $string_id));
                 icl_update_string_status($string_id);
             } else {
                 $orig_data = array('string_id' => $string_id, 'language' => $source_lang);
                 $update_string['status'] = ICL_TM_COMPLETE;
                 if ($this->wpdb->get_var($this->wpdb->prepare("SELECT COUNT(*)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  FROM {$this->wpdb->prefix}icl_string_translations\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  WHERE string_id = %d\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  \tAND language = %s", $string_id, $source_lang))) {
                     $this->wpdb->update($this->wpdb->prefix . 'icl_string_translations', $update_string, $orig_data);
                 } else {
                     $this->wpdb->insert($this->wpdb->prefix . 'icl_string_translations', array_merge($update_string, $orig_data));
                 }
                 icl_update_string_status($string_id);
             }
         }
     } else {
         $string_id = $this->save_string($value, $allow_empty_value, $source_lang, $domain, $context, $name);
     }
     if (defined('WPML_TM_PATH') && !empty($WPML_Sticky_Links) && $WPML_Sticky_Links->settings['sticky_links_strings']) {
         require_once WPML_TM_PATH . '/inc/translation-proxy/wpml-pro-translation.class.php';
         WPML_Pro_Translation::_content_make_links_sticky($string_id, 'string', false);
     }
     if (!isset($this->name_cache[$key])) {
         $this->name_cache[$key] = $value;
     }
     return $string_id;
 }
 /**
  * Synchronizes language pairs with ICL
  *
  * @global object $sitepress
  *
  * @param $project
  * @param $language_pairs
  *
  */
 public static function update_language_pairs($project, $language_pairs)
 {
     global $sitepress;
     $params = array('site_id' => $project->ts_id, 'accesskey' => $project->ts_access_key, 'create_account' => 0);
     $lang_server = array();
     foreach ($sitepress->get_active_languages() as $lang) {
         $lang_server[$lang['code']] = WPML_Pro_Translation::server_languages_map($lang['english_name']);
     }
     // update account - add language pair
     $incr = 0;
     foreach ($language_pairs as $k => $v) {
         foreach ($v as $k2 => $v2) {
             $incr++;
             $params['from_language' . $incr] = $lang_server[$k];
             $params['to_language' . $incr] = $lang_server[$k2];
         }
     }
     require_once ICL_PLUGIN_PATH . '/lib/Snoopy.class.php';
     require_once ICL_PLUGIN_PATH . '/lib/xml2array.php';
     require_once ICL_PLUGIN_PATH . '/lib/icl_api.php';
     $icl_query = new ICanLocalizeQuery();
     $icl_query->updateAccount($params);
 }
 /**
  * Get information about translators from current project. Works only for ICL as a Translation Service
  *
  * @param bool $force
  *
  * @return array|bool
  */
 public static function get_icl_translator_status($force = false)
 {
     /** @var SitePress $sitepress */
     /** @var WPML_Pro_Translation $ICL_Pro_Translation */
     global $sitepress, $ICL_Pro_Translation;
     if (!$ICL_Pro_Translation) {
         $job_factory = wpml_tm_load_job_factory();
         $ICL_Pro_Translation = new WPML_Pro_Translation($job_factory);
     }
     if (!TranslationProxy::translator_selection_available()) {
         return array();
     }
     $project = TranslationProxy::get_current_project();
     if (!$project) {
         return array();
     }
     $cache_key = md5(serialize($project));
     $cache_group = 'get_icl_translator_status';
     $found = false;
     $result = wp_cache_get($cache_key, $cache_group, false, $found);
     if ($found) {
         return $result;
     }
     $translator_status = array();
     $website_details = self::get_website_details(new TranslationProxy_Project(TranslationProxy::get_current_service()), $force);
     if (false === (bool) $website_details) {
         return array();
     }
     $language_pairs = array();
     if (isset($website_details['translation_languages']['translation_language'])) {
         $translation_languages = $website_details['translation_languages']['translation_language'];
         if (!isset($translation_languages[0])) {
             $buf = $translation_languages;
             $translation_languages = array(0 => $buf);
         }
         foreach ($translation_languages as $lang) {
             $translators = $_tr = array();
             $max_rate = false;
             if (isset($lang['translators'], $lang['translators']['translator']) && !empty($lang['translators'])) {
                 if (!isset($lang['translators']['translator'][0])) {
                     $_tr[0] = $lang['translators']['translator'];
                 } else {
                     $_tr = $lang['translators']['translator'];
                 }
                 foreach ($_tr as $t) {
                     if (false === $max_rate || $t['attr']['amount'] > $max_rate) {
                         $max_rate = $t['attr']['amount'];
                     }
                     $translators[] = array('id' => $t['attr']['id'], 'nickname' => $t['attr']['nickname'], 'contract_id' => $t['attr']['contract_id']);
                 }
             }
             $language_pairs[] = array('from' => $sitepress->get_language_code($ICL_Pro_Translation->server_languages_map($lang['attr']['from_language_name'], true)), 'to' => $sitepress->get_language_code($ICL_Pro_Translation->server_languages_map($lang['attr']['to_language_name'], true)), 'have_translators' => $lang['attr']['have_translators'], 'available_translators' => $lang['attr']['available_translators'], 'applications' => $lang['attr']['applications'], 'contract_id' => $lang['attr']['contract_id'], 'id' => $lang['attr']['id'], 'translators' => $translators, 'max_rate' => $max_rate);
         }
     }
     $translator_status['icl_lang_status'] = $language_pairs;
     if (isset($res['client']['attr'])) {
         $translator_status['icl_balance'] = $res['client']['attr']['balance'];
         $translator_status['icl_anonymous_user'] = $res['client']['attr']['anon'];
     }
     if (isset($res['html_status']['value'])) {
         $translator_status['icl_html_status'] = html_entity_decode($res['html_status']['value']);
         $translator_status['icl_html_status'] = preg_replace_callback('#<a([^>]*)href="([^"]+)"([^>]*)>#i', create_function('$matches', 'global $sitepress; return TranslationProxy_Popup::get_link($matches[2]);'), $translator_status['icl_html_status']);
     }
     if (isset($res['translators_management_info']['value'])) {
         $translator_status['translators_management_info'] = html_entity_decode($res['translators_management_info']['value']);
         $translator_status['translators_management_info'] = preg_replace_callback('#<a([^>]*)href="([^"]+)"([^>]*)>#i', create_function('$matches', 'global $sitepress; return TranslationProxy_Popup::get_link($matches[2]);'), $translator_status['translators_management_info']);
     }
     $translator_status['icl_support_ticket_id'] = null;
     if (isset($res['attr']['support_ticket_id'])) {
         $translator_status['icl_support_ticket_id'] = (int) $res['attr']['support_ticket_id'];
     }
     wp_cache_set($cache_key, $translator_status, $cache_group);
     return $translator_status;
 }