public function mergeALL(ArrayObject $projectStructure, $renewPassword = false) { $query_job = "SELECT *\n FROM jobs\n WHERE id = %u\n ORDER BY job_first_segment"; $query_job = sprintf($query_job, $projectStructure['job_to_merge']); //$projectStructure[ 'job_to_split' ] $rows = $this->dbHandler->fetch_array($query_job); //get the min and $first_job = reset($rows); $job_first_segment = $first_job['job_first_segment']; //the max segment from job list $last_job = end($rows); $job_last_segment = $last_job['job_last_segment']; //change values of first job $first_job['job_first_segment'] = $job_first_segment; // redundant $first_job['job_last_segment'] = $job_last_segment; //merge TM keys: preserve only owner's keys $tm_keys = array(); foreach ($rows as $chunk_info) { $tm_keys[] = $chunk_info['tm_keys']; } try { $owner_tm_keys = TmKeyManagement_TmKeyManagement::getOwnerKeys($tm_keys); /** * @var $owner_key TmKeyManagement_TmKeyStruct */ foreach ($owner_tm_keys as $i => $owner_key) { $owner_tm_keys[$i] = $owner_key->toArray(); } $first_job['tm_keys'] = json_encode($owner_tm_keys); } catch (Exception $e) { Log::doLog(__METHOD__ . " -> Merge Jobs error - TM key problem: " . $e->getMessage()); } $oldPassword = $first_job['password']; if ($renewPassword) { $first_job['password'] = self::_generatePassword(); } $_data = array(); foreach ($first_job as $field => $value) { $_data[] = "`{$field}`='{$value}'"; } //---------------------------------------------------- $queries = array(); $queries[] = "UPDATE jobs SET " . implode(", \n", $_data) . " WHERE id = {$first_job['id']} AND password = '******'"; //ose old password //delete all old jobs $queries[] = "DELETE FROM jobs WHERE id = {$first_job['id']} AND password != '{$first_job['password']}' "; //use new password foreach ($queries as $query) { $res = $this->dbHandler->query($query); if ($res !== true) { $msg = "Failed to merge job " . $rows[0]['id'] . " from " . count($rows) . " chunks\n"; $msg .= "Tried to perform SQL: \n" . print_r($queries, true) . " \n\n"; $msg .= "Failed Statement is: \n" . print_r($query, true) . "\n"; $msg .= "Original Status for rebuild job and project was: \n" . print_r($rows, true) . "\n"; Utils::sendErrMailReport($msg); throw new Exception('Failed to merge jobs, project damaged. Contact Matecat Support to rebuild project.', -8); } } $wCountManager = new WordCount_Counter(); $wCountManager->initializeJobWordCount($first_job['id'], $first_job['password']); Shop_Cart::getInstance('outsource_to_external_cache')->emptyCart(); }
/** * Add a cart element in the specified Shop_Cart. * In order to add an element, it is necessary to delete it first. Therefore "delItem" function is called first. * * IMPORTANT: how deletion works. * "delItem" function deletes ALL the carts starting with $idToUse. * Hence, even a partial matching is accepted and the element is deleted. * * This function always receives $cartElem parameters whose id is always in the form: * JOBID-JOBPASSWORD-outsourced <- when caching outsourced jobs * JOBID-JOBPASSWORD-INTEGER <- when caching normal quotes * * In case delItem is called with the full $cartElem ID (when parameter $deleteOnPartialMatch is false) * only one element (at most) in the cart will match the whole id, therefore a single deletion is made. * In case delItem is called with only job id and password as ID (when parameter $deleteOnPartialMatch is true) * all the data about that job (regardless of the delivery date or whether it was outsourced or not) is deleted. * * * @see OutsourceTo_Translated::__processOutsourcedJobs for when parameter $deleteOnPartialMatch is set to true * * @param Shop_ItemHTSQuoteJob $cartElem * @param string $cartName * @param bool $deleteOnPartialMatch * */ private function __addCartElementToCart($cartElem, $cartName, $deleteOnPartialMatch) { $idToUse = $deleteOnPartialMatch ? substr($cartElem["id"], 0, strrpos($cartElem["id"], "-")) : $cartElem["id"]; Shop_Cart::getInstance($cartName)->delItem($idToUse); Shop_Cart::getInstance($cartName)->addItem($cartElem); }
/** * Perform a quote on the remote Provider server * * @see OutsourceTo_AbstractProvider::performQuote * * @param array|null $volAnalysis */ public function performQuote($volAnalysis = null) { /** * cache this job info for 20 minutes ( session duration ) */ $cache_cart = Shop_Cart::getInstance('outsource_to_external_cache'); if ($volAnalysis == null) { //call matecat API for Project status and information $project_url_api = INIT::$HTTPHOST . INIT::$BASEURL . "api/status?id_project=" . $this->pid . "&project_pass="******"Project Not Found in Cache. Call API url for STATUS: " . $project_url_api); $options = array(CURLOPT_HEADER => false, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => 0, CURLOPT_USERAGENT => INIT::MATECAT_USER_AGENT . INIT::$BUILD_NUMBER, CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2); //prepare handlers for curl to quote service $mh = new MultiCurlHandler(); $resourceHash = $mh->createResource($project_url_api, $options); $mh->multiExec(); if ($mh->hasError($resourceHash)) { Log::doLog($mh->getError($resourceHash)); } $raw_volAnalysis = $mh->getSingleContent($resourceHash); $mh->multiCurlCloseAll(); //retrieve the project subject: pick the project's first job and get the subject $jobData = getJobData($this->jobList[0]['jid'], $this->jobList[0]['jpassword']); $subject = $jobData['subject']; $itemCart = new Shop_ItemHTSQuoteJob(); $itemCart['id'] = $project_url_api; $itemCart['show_info'] = $raw_volAnalysis; $itemCart['subject'] = $subject; $cache_cart->addItem($itemCart); } else { $tmp_project_cache = $cache_cart->getItem($project_url_api); $raw_volAnalysis = $tmp_project_cache['show_info']; $subject = $tmp_project_cache['subject']; } // Log::doLog( $raw_volAnalysis ); $volAnalysis = json_decode($raw_volAnalysis, true); } // Log::doLog( $volAnalysis ); $_jobLangs = array(); $options = array(CURLOPT_HEADER => false, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => 0, CURLOPT_USERAGENT => INIT::MATECAT_USER_AGENT . INIT::$BUILD_NUMBER, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2); //prepare handlers for curl to quote service $mh = new MultiCurlHandler(); foreach ($this->jobList as $job) { //trim decimals to int $job_payableWords = (int) $volAnalysis['data']['jobs'][$job['jid']]['totals'][$job['jpassword']]['TOTAL_PAYABLE'][0]; /* * //languages are in the form: * * "langpairs":{ * "5888-e94bd2f79afd":"en-GB|fr-FR", * "5889-c853a841dafd":"en-GB|de-DE", * "5890-e852ca45c66e":"en-GB|it-IT", * "5891-b43f2f067319":"en-GB|es-ES" * }, * */ $langPairs = $volAnalysis['jobs']['langpairs'][$job['jid'] . "-" . $job['jpassword']]; $_langPairs_array = explode("|", $langPairs); $source = $_langPairs_array[0]; $target = $_langPairs_array[1]; //save langpairs of the jobs $_jobLangs[$job['jid'] . "-" . $job['jpassword']]['source'] = $source; $_jobLangs[$job['jid'] . "-" . $job['jpassword']]['target'] = $target; $url = "https://www.translated.net/hts/?f=quote&cid=htsdemo&p=htsdemo5&s={$source}&t={$target}&pn=MATECAT_{$job['jid']}-{$job['jpassword']}&w={$job_payableWords}&df=matecat&matecat_pid=" . $this->pid . "&matecat_ppass="******"&matecat_pname=" . $volAnalysis['data']['summary']['NAME'] . "&subject=" . $subject; if (!$cache_cart->itemExists($job['jid'] . "-" . $job['jpassword'])) { Log::doLog("Not Found in Cache. Call url for Quote: " . $url); $tokenHash = $mh->createResource($url, $options, $job['jid'] . "-" . $job['jpassword']); } else { $cartElem = $cache_cart->getItem($job['jid'] . "-" . $job['jpassword']); $cartElem["currency"] = $this->currency; $cartElem["timezone"] = $this->timezone; $cache_cart->delItem($job['jid'] . "-" . $job['jpassword']); $cache_cart->addItem($cartElem); } } $mh->multiExec(); $res = $mh->getAllContents(); $failures = array(); //fetch contents and store in cache if there are foreach ($res as $jpid => $quote) { if ($mh->hasError($jpid)) { Log::doLog($mh->getError($jpid)); } /* * Quotes are plain text line feed separated fields in the form: * 1 * OK * 2014-04-16T09:30:00Z * 488 * 46.36 * 11140320 * 1 */ Log::doLog($quote); $result_quote = explode("\n", $quote); $itemCart = new Shop_ItemHTSQuoteJob(); $itemCart['id'] = $jpid; $itemCart['project_name'] = $volAnalysis['data']['summary']['NAME']; $itemCart['name'] = "MATECAT_{$jpid}"; $itemCart['delivery_date'] = $result_quote[2]; $itemCart['words'] = $result_quote[3]; $itemCart['price'] = $result_quote[4] ? $result_quote[4] : 0; $itemCart['currency'] = $this->currency; $itemCart['timezone'] = $this->timezone; $itemCart['quote_pid'] = $result_quote[5]; $itemCart['source'] = $_jobLangs[$jpid]['source']; //get the right language $itemCart['target'] = $_jobLangs[$jpid]['target']; //get the right language $itemCart['show_info'] = $result_quote[6]; $itemCart['subject'] = $subject; $cache_cart->addItem($itemCart); Log::doLog($itemCart); //Oops we got an error if ($itemCart['price'] == 0 && empty($itemCart['words'])) { $failures[$jpid] = $jpid; } } $shopping_cart = Shop_Cart::getInstance('outsource_to_external'); //now get the right contents foreach ($this->jobList as $job) { $shopping_cart->delItem($job['jid'] . "-" . $job['jpassword']); $shopping_cart->addItem($cache_cart->getItem($job['jid'] . "-" . $job['jpassword'])); $this->_quote_result = array($shopping_cart->getItem($job['jid'] . "-" . $job['jpassword'])); } //check for failures.. destroy the cache if (!empty($failures)) { foreach ($failures as $jpid) { $cache_cart->delItem($jpid); } } }
/** * Set the template vars to the redirect Page * * @return mixed|void */ public function setTemplateVars() { $shop_cart = Shop_Cart::getInstance('outsource_to_external'); if (!$shop_cart->countItems()) { /** * redirectFailurePage is a white page with an error for session expired * */ parent::makeTemplate("redirectFailurePage.html"); return null; } else { /** * redirectSuccessPage is a white page with a form submitted by javascript * */ parent::makeTemplate("redirectSuccessPage.html"); } //we need a list not an hashmap $item_list = array(); foreach (array($shop_cart->getItem($this->data_key_content)) as $item) { $item_list[] = $item; } $this->template->tokenAuth = $this->tokenAuth; $this->template->data = json_encode($item_list); $this->template->redirect_url = $this->review_order_page; $this->template->data_key = $this->data_key_content; //clear the cart after redirection //$shop_cart->emptyCart(); }