public function doAction()
 {
     $this->result['token'] = $this->token;
     if (empty($this->job)) {
         $this->result['errors'][] = array("code" => -2, "message" => "missing id job");
         return;
     }
     //get Job Info
     $this->job_data = getJobData((int) $this->job, $this->password);
     $pCheck = new AjaxPasswordCheck();
     //check for Password correctness
     if (!$pCheck->grantJobAccessByJobData($this->job_data, $this->password)) {
         $this->result['errors'][] = array("code" => -10, "message" => "wrong password");
         return;
     }
     switch ($this->function) {
         case 'find':
             $this->doSearch();
             break;
         case 'replaceAll':
             $this->doReplaceAll();
             break;
         default:
             $this->result['errors'][] = array("code" => -11, "message" => "unknown  function. Use find or replace");
             return;
     }
 }
 /**
  * When Called it perform the controller action to retrieve/manipulate data
  *
  * @return mixed
  */
 function doAction()
 {
     if (count($this->errors) > 0) {
         return null;
     }
     //get job language and data
     //Fixed Bug: need a specific job, because we need The target Language
     //Removed from within the foreach cycle, the job is always the same...
     $jobData = $this->jobInfo = getJobData($this->jobID, $this->jobPass);
     $pCheck = new AjaxPasswordCheck();
     //check for Password correctness
     if (empty($jobData) || !$pCheck->grantJobAccessByJobData($jobData, $this->jobPass)) {
         $msg = "Error : wrong password provided for download \n\n " . var_export($_POST, true) . "\n";
         Log::doLog($msg);
         Utils::sendErrMailReport($msg);
         return null;
     }
     $projectData = getProject($jobData['id_project']);
     $source = $jobData['source'];
     $target = $jobData['target'];
     $tmsService = new TMSService();
     /**
      * @var $tmx SplTempFileObject
      */
     $this->tmx = $tmsService->exportJobAsTMX($this->jobID, $this->jobPass, $source, $target);
     $this->fileName = $projectData[0]['name'] . "-" . $this->jobID . ".tmx";
 }
 public function doAction()
 {
     if (empty($this->segment)) {
         $this->result['errors'][] = array("code" => -1, "message" => "missing source segment");
     }
     if (empty($this->translation)) {
         $this->result['errors'][] = array("code" => -2, "message" => "missing target translation");
     }
     if (empty($this->source_lang)) {
         $this->result['errors'][] = array("code" => -3, "message" => "missing source lang");
     }
     if (empty($this->target_lang)) {
         $this->result['errors'][] = array("code" => -4, "message" => "missing target lang");
     }
     if (empty($this->time_to_edit)) {
         $this->result['errors'][] = array("code" => -5, "message" => "missing time to edit");
     }
     if (empty($this->id_segment)) {
         $this->result['errors'][] = array("code" => -6, "message" => "missing segment id");
     }
     //get Job Infos, we need only a row of jobs ( split )
     $job_data = getJobData((int) $this->id_job, $this->password);
     $pCheck = new AjaxPasswordCheck();
     //check for Password correctness
     if (empty($job_data) || !$pCheck->grantJobAccessByJobData($job_data, $this->password)) {
         $this->result['errors'][] = array("code" => -10, "message" => "wrong password");
         $msg = "\n\n Error \n\n " . var_export(array_merge($this->result, $_POST), true);
         Log::doLog($msg);
         Utils::sendErrMailReport($msg);
         return;
     }
     //mt engine to contribute to
     if ($job_data['id_mt_engine'] <= 1) {
         return false;
     }
     $this->mt = Engine::getInstance($job_data['id_mt_engine']);
     //array of storicised suggestions for current segment
     $this->suggestion_json_array = json_decode(getArrayOfSuggestionsJSON($this->id_segment), true);
     //extra parameters
     $extra = json_encode(array('id_segment' => $this->id_segment, 'suggestion_json_array' => $this->suggestion_json_array, 'chosen_suggestion_index' => $this->chosen_suggestion_index, 'time_to_edit' => $this->time_to_edit));
     //send stuff
     $config = $this->mt->getConfigStruct();
     $config['segment'] = CatUtils::view2rawxliff($this->segment);
     $config['translation'] = CatUtils::view2rawxliff($this->translation);
     $config['source'] = $this->source_lang;
     $config['target'] = $this->target_lang;
     $config['email'] = INIT::$MYMEMORY_API_KEY;
     $config['segid'] = $this->id_segment;
     $config['extra'] = $extra;
     $config['id_user'] = array("TESTKEY");
     $outcome = $this->mt->set($config);
     if ($outcome->error->code < 0) {
         $this->result['errors'] = $outcome->error->get_as_array();
     }
 }
 protected function _checkData($logName = 'log.txt')
 {
     //change Log file
     Log::$fileName = $logName;
     $this->parseIDSegment();
     if (empty($this->id_segment)) {
         $this->result['errors'][] = array("code" => -1, "message" => "missing id_segment");
     }
     //strtoupper transforms null to "" so check for the first element to be an empty string
     if (!empty($this->split_statuses[0]) && !empty($this->split_num)) {
         if (count(array_unique($this->split_statuses)) == 1) {
             //IF ALL translation chunks are in the same status, we take the status for the entire segment
             $this->status = $this->split_statuses[0];
         } else {
             $this->status = Constants_TranslationStatus::STATUS_DRAFT;
         }
         foreach ($this->split_statuses as $pos => $value) {
             $this->_checkForStatus($value);
         }
     } else {
         $this->_checkForStatus($this->status);
     }
     if (empty($this->id_job)) {
         $this->result['errors'][] = array("code" => -2, "message" => "missing id_job");
     } else {
         //get Job Info, we need only a row of jobs ( split )
         $this->jobData = $job_data = getJobData((int) $this->id_job, $this->password);
         if (empty($job_data)) {
             $msg = "Error : empty job data \n\n " . var_export($_POST, true) . "\n";
             Log::doLog($msg);
             Utils::sendErrMailReport($msg);
         }
         //add check for job status archived.
         if (strtolower($job_data['status']) == Constants_JobStatus::STATUS_ARCHIVED) {
             $this->result['errors'][] = array("code" => -3, "message" => "job archived");
         }
         //check for Password correctness ( remove segment split )
         $pCheck = new AjaxPasswordCheck();
         if (empty($job_data) || !$pCheck->grantJobAccessByJobData($job_data, $this->password, $this->id_segment)) {
             $this->result['errors'][] = array("code" => -10, "message" => "wrong password");
         }
     }
     //ONE OR MORE ERRORS OCCURRED : EXITING
     if (!empty($this->result['errors'])) {
         $msg = "Error \n\n " . var_export(array_merge($this->result, $_POST), true);
         throw new Exception($msg, -1);
     }
     if (is_null($this->translation) || $this->translation === '') {
         Log::doLog("Empty Translation \n\n" . var_export($_POST, true));
         // won't save empty translation but there is no need to return an errors
         throw new Exception("Empty Translation \n\n" . var_export($_POST, true), 0);
     }
 }
 public function doAction()
 {
     $this->job = getJobData($this->__postInput['id_job'], $this->__postInput['password']);
     $this->checkLogin();
     if ($this->userIsLogged) {
         $this->loadUser();
     }
     $pCheck = new AjaxPasswordCheck();
     if (!$pCheck->grantJobAccessByJobData($this->job, $this->__postInput['password'])) {
         $this->result['errors'][] = array("code" => -10, "message" => "wrong password");
         return;
     }
     $this->route();
 }
 public function doAction()
 {
     if (empty($this->id_project)) {
         $this->result['errors'] = array(-1, "No id project provided");
         return -1;
     }
     $_project_data = getProjectJobData($this->id_project);
     $passCheck = new AjaxPasswordCheck();
     $access = $passCheck->grantProjectAccess($_project_data, $this->ppassword) || $passCheck->grantProjectJobAccessOnJobPass($_project_data, null, $this->jpassword);
     if (!$access) {
         $this->result['errors'] = array(-10, "Wrong Password. Access denied");
         return -1;
     }
     $analysisStatus = new Analysis_WEBStatus($_project_data);
     $this->result = $analysisStatus->fetchData()->getResult();
 }
 /**
  * When Called it perform the controller action to retrieve/manipulate data
  *
  * @return mixed
  */
 function doAction()
 {
     $_project_data = getProjectJobData($this->id_project);
     $pCheck = new AjaxPasswordCheck();
     $access = $pCheck->grantProjectAccess($_project_data, $this->password);
     //check for Password correctness
     if (!$access) {
         $msg = "Error : wrong password provided for download \n\n " . var_export($_POST, true) . "\n";
         Log::doLog($msg);
         Utils::sendErrMailReport($msg);
         return null;
     }
     $analysisStatus = new Analysis_XTRFStatus($_project_data);
     $outputContent = $analysisStatus->fetchData()->getResult();
     $this->content = $this->composeZip($_project_data[0]['pname'], $outputContent);
     $this->_filename = $_project_data[0]['pname'] . ".zip";
 }
 public function __construct()
 {
     parent::__construct();
     //Session Enabled
     //define input filters
     $filterArgs = array('job_id' => array('filter' => FILTER_SANITIZE_NUMBER_INT), 'job_pass' => array('filter' => FILTER_SANITIZE_STRING, 'flags' => FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH));
     //filter input
     $_postInput = filter_input_array(INPUT_POST, $filterArgs);
     //assign variables
     $this->job_id = $_postInput['job_id'];
     $this->job_pass = $_postInput['job_pass'];
     $this->tm_keys = $_POST['data'];
     // this will be filtered inside the TmKeyManagement class
     //check for eventual errors on the input passed
     $this->result['errors'] = array();
     if (empty($this->job_id)) {
         $this->result['errors'][] = array('code' => -1, 'message' => "Job id missing");
     }
     if (empty($this->job_pass)) {
         $this->result['errors'][] = array('code' => -2, 'message' => "Job pass missing");
     }
     //get job data
     $this->jobData = getJobData($this->job_id, $this->job_pass);
     //Check if user can access the job
     $pCheck = new AjaxPasswordCheck();
     //check for Password correctness
     if (empty($this->jobData) || !$pCheck->grantJobAccessByJobData($this->jobData, $this->job_pass)) {
         $this->result['errors'][] = array("code" => -10, "message" => "Wrong password");
     }
     $this->checkLogin();
     if (self::isRevision()) {
         $this->userRole = TmKeyManagement_Filter::ROLE_REVISOR;
     } elseif ($this->userMail == $this->jobData['owner']) {
         $this->userRole = TmKeyManagement_Filter::OWNER;
     }
 }
 public function doAction()
 {
     //get Job Infos
     $job_data = getJobData($this->jid);
     $pCheck = new AjaxPasswordCheck();
     //check for Password correctness
     if (!$pCheck->grantJobAccessByJobData($job_data, $this->password)) {
         $this->result['errors'][] = array("code" => -10, "message" => "wrong password");
         return;
     }
     $lang_handler = Langs_Languages::getInstance();
     if ($this->ref_segment == '') {
         $this->ref_segment = 0;
     }
     $data = getMoreSegments($this->jid, $this->password, $this->step, $this->ref_segment, $this->where);
     $this->prepareNotes($data);
     foreach ($data as $i => $seg) {
         if ($this->where == 'before') {
             if ((double) $seg['sid'] >= (double) $this->ref_segment) {
                 break;
             }
         }
         if (empty($this->pname)) {
             $this->pname = $seg['pname'];
         }
         if (empty($this->last_opened_segment)) {
             $this->last_opened_segment = $seg['last_opened_segment'];
         }
         if (empty($this->cid)) {
             $this->cid = $seg['cid'];
         }
         if (empty($this->pid)) {
             $this->pid = $seg['pid'];
         }
         if (empty($this->tid)) {
             $this->tid = $seg['tid'];
         }
         if (empty($this->create_date)) {
             $this->create_date = $seg['create_date'];
         }
         if (empty($this->source_code)) {
             $this->source_code = $seg['source'];
         }
         if (empty($this->target_code)) {
             $this->target_code = $seg['target'];
         }
         if (empty($this->source)) {
             $s = explode("-", $seg['source']);
             $source = strtoupper($s[0]);
             $this->source = $source;
         }
         if (empty($this->target)) {
             $t = explode("-", $seg['target']);
             $target = strtoupper($t[0]);
             $this->target = $target;
         }
         if (empty($this->err)) {
             $this->err = $seg['serialized_errors_list'];
         }
         $id_file = $seg['id_file'];
         if (!isset($this->data["{$id_file}"])) {
             $this->data["{$id_file}"]['jid'] = $seg['jid'];
             $this->data["{$id_file}"]["filename"] = ZipArchiveExtended::getFileName($seg['filename']);
             $this->data["{$id_file}"]["mime_type"] = $seg['mime_type'];
             $this->data["{$id_file}"]['source'] = $lang_handler->getLocalizedName($seg['source']);
             $this->data["{$id_file}"]['target'] = $lang_handler->getLocalizedName($seg['target']);
             $this->data["{$id_file}"]['source_code'] = $seg['source'];
             $this->data["{$id_file}"]['target_code'] = $seg['target'];
             $this->data["{$id_file}"]['segments'] = array();
         }
         unset($seg['id_file']);
         unset($seg['source']);
         unset($seg['target']);
         unset($seg['source_code']);
         unset($seg['target_code']);
         unset($seg['mime_type']);
         unset($seg['filename']);
         unset($seg['jid']);
         unset($seg['pid']);
         unset($seg['cid']);
         unset($seg['tid']);
         unset($seg['pname']);
         unset($seg['create_date']);
         unset($seg['id_segment_end']);
         unset($seg['id_segment_start']);
         unset($seg['serialized_errors_list']);
         $seg['parsed_time_to_edit'] = CatUtils::parse_time_to_edit($seg['time_to_edit']);
         $seg['source_chunk_lengths'] === null ? $seg['source_chunk_lengths'] = '[]' : null;
         $seg['target_chunk_lengths'] === null ? $seg['target_chunk_lengths'] = '{"len":[0],"statuses":["DRAFT"]}' : null;
         $seg['source_chunk_lengths'] = json_decode($seg['source_chunk_lengths'], true);
         $seg['target_chunk_lengths'] = json_decode($seg['target_chunk_lengths'], true);
         $seg['segment'] = CatUtils::rawxliff2view(CatUtils::reApplySegmentSplit($seg['segment'], $seg['source_chunk_lengths']));
         $seg['translation'] = CatUtils::rawxliff2view(CatUtils::reApplySegmentSplit($seg['translation'], $seg['target_chunk_lengths']['len']));
         $this->attachNotes($seg);
         $this->data["{$id_file}"]['segments'][] = $seg;
     }
     $this->result['data']['files'] = $this->data;
     $this->result['data']['where'] = $this->where;
 }
 public function doAction()
 {
     if (!$this->concordance_search) {
         //execute these lines only in segment contribution search,
         //in case of user concordance search skip these lines
         //because segment can be optional
         if (empty($this->id_segment)) {
             $this->result['errors'][] = array("code" => -1, "message" => "missing id_segment");
         }
     }
     if (is_null($this->text) || $this->text === '') {
         $this->result['errors'][] = array("code" => -2, "message" => "missing text");
     }
     if (empty($this->id_job)) {
         $this->result['errors'][] = array("code" => -3, "message" => "missing id_job");
     }
     if (empty($this->num_results)) {
         $this->num_results = INIT::$DEFAULT_NUM_RESULTS_FROM_TM;
     }
     if (!empty($this->result['errors'])) {
         return -1;
     }
     //get Job Infos, we need only a row of jobs ( split )
     $this->jobData = getJobData($this->id_job, $this->password);
     $pCheck = new AjaxPasswordCheck();
     //check for Password correctness
     if (empty($this->jobData) || !$pCheck->grantJobAccessByJobData($this->jobData, $this->password)) {
         $this->result['errors'][] = array("code" => -10, "message" => "wrong password");
         return -1;
     }
     /*
      * string manipulation strategy
      *
      */
     if (!$this->concordance_search) {
         //
         $this->text = CatUtils::view2rawxliff($this->text);
         $this->source = $this->jobData['source'];
         $this->target = $this->jobData['target'];
     } else {
         $regularExpressions = $this->tokenizeSourceSearch();
         if ($this->switch_languages) {
             /*
              *
              * switch languages from user concordances search on the target language value
              * Example:
              * Job is in
              *      source: it_IT,
              *      target: de_DE
              *
              * user perform a right click for concordance help on a german word or phrase
              * we want result in italian from german source
              *
              */
             $this->source = $this->jobData['target'];
             $this->target = $this->jobData['source'];
         } else {
             $this->source = $this->jobData['source'];
             $this->target = $this->jobData['target'];
         }
     }
     $this->id_mt_engine = $this->jobData['id_mt_engine'];
     $this->id_tms = $this->jobData['id_tms'];
     $this->tm_keys = $this->jobData['tm_keys'];
     $config = array();
     if ($this->id_tms == 1) {
         /**
          * MyMemory Enabled
          */
         $config['get_mt'] = true;
         $config['mt_only'] = false;
         if ($this->id_mt_engine != 1) {
             /**
              * Don't get MT contribution from MyMemory ( Custom MT )
              */
             $config['get_mt'] = false;
         }
         $_TMS = $this->id_tms;
     } else {
         if ($this->id_tms == 0 && $this->id_mt_engine == 1) {
             /**
              * MyMemory disabled but MT Enabled and it is NOT a Custom one
              * So tell to MyMemory to get MT only
              */
             $config['get_mt'] = true;
             $config['mt_only'] = true;
             $_TMS = 1;
             /* MyMemory */
         }
     }
     /**
      * if No TM server and No MT selected $_TMS is not defined
      * so we want not to perform TMS Call
      *
      */
     if (isset($_TMS)) {
         /**
          * @var $tms Engines_MyMemory
          */
         $tms = Engine::getInstance($_TMS);
         $config = array_merge($tms->getConfigStruct(), $config);
         $config['segment'] = $this->text;
         $config['source'] = $this->source;
         $config['target'] = $this->target;
         $config['email'] = INIT::$MYMEMORY_API_KEY;
         $config['id_user'] = array();
         $config['num_result'] = $this->num_results;
         $config['isConcordance'] = $this->concordance_search;
         //get job's TM keys
         $this->checkLogin();
         try {
             if (self::isRevision()) {
                 $this->userRole = TmKeyManagement_Filter::ROLE_REVISOR;
             }
             $tm_keys = TmKeyManagement_TmKeyManagement::getJobTmKeys($this->tm_keys, 'r', 'tm', $this->uid, $this->userRole);
             if (is_array($tm_keys) && !empty($tm_keys)) {
                 foreach ($tm_keys as $tm_key) {
                     $config['id_user'][] = $tm_key->key;
                 }
             }
         } catch (Exception $e) {
             $this->result['errors'][] = array("code" => -11, "message" => "Cannot retrieve TM keys info.");
             Log::doLog($e->getMessage());
             return;
         }
         $tms_match = $tms->get($config);
         $tms_match = $tms_match->get_matches_as_array();
     }
     if ($this->id_mt_engine > 1) {
         /**
          * @var $mt Engines_Moses
          */
         $mt = Engine::getInstance($this->id_mt_engine);
         $config = $mt->getConfigStruct();
         $config['segment'] = $this->text;
         $config['source'] = $this->source;
         $config['target'] = $this->target;
         $config['id_user'] = INIT::$MYMEMORY_API_KEY;
         $config['segid'] = $this->id_segment;
         $mt_result = $mt->get($config);
         if (isset($mt_result['error']['code'])) {
             $mt_result['error']['created_by_type'] = 'MT';
             $this->result['errors'][] = $mt_result['error'];
             $mt_result = false;
         }
     }
     $matches = array();
     if (!empty($tms_match)) {
         $matches = $tms_match;
     }
     if (!empty($mt_result)) {
         $matches[] = $mt_result;
         usort($matches, array("getContributionController", "__compareScore"));
         //this is necessary since usort sorts is ascending order, thus inverting the ranking
         $matches = array_reverse($matches);
     }
     $matches = array_slice($matches, 0, $this->num_results);
     isset($matches[0]['match']) ? $firstMatchVal = floatval($matches[0]['match']) : null;
     if (isset($firstMatchVal) && $firstMatchVal >= 90 && $firstMatchVal < 100) {
         $srcSearch = strip_tags($this->text);
         $segmentFound = strip_tags($matches[0]['raw_segment']);
         $srcSearch = mb_strtolower(preg_replace('#[\\x{20}]{2,}#u', chr(0x20), $srcSearch));
         $segmentFound = mb_strtolower(preg_replace('#[\\x{20}]{2,}#u', chr(0x20), $segmentFound));
         $fuzzy = levenshtein($srcSearch, $segmentFound) / log10(mb_strlen($srcSearch . $segmentFound) + 1);
         //levenshtein handle max 255 chars per string and returns -1, so fuzzy var can be less than 0 !!
         if ($srcSearch == $segmentFound || $fuzzy < 2.5 && $fuzzy >= 0) {
             $qaRealign = new QA($this->text, html_entity_decode($matches[0]['raw_translation']));
             $qaRealign->tryRealignTagID();
             $log_prepend = "CLIENT REALIGN IDS PROCEDURE | ";
             if (!$qaRealign->thereAreErrors()) {
                 /*
                 Log::doLog( $log_prepend . " - Requested Segment: " . var_export( $this->__postInput, true) );
                 Log::doLog( $log_prepend . "Fuzzy: " . $fuzzy .  " - Try to Execute Tag ID Realignment." );
                 Log::doLog( $log_prepend . "TMS RAW RESULT:" );
                 Log::doLog( $log_prepend . var_export($matches[0], true) );
                 Log::doLog( $log_prepend . "Realignment Success:");
                 */
                 $matches[0]['segment'] = CatUtils::rawxliff2view($this->text);
                 $matches[0]['translation'] = CatUtils::rawxliff2view($qaRealign->getTrgNormalized());
                 $matches[0]['match'] = $fuzzy == 0 ? '100%' : '99%';
                 /*
                                     Log::doLog( $log_prepend . "View Segment:     " . var_export($matches[0]['segment'], true) );
                                     Log::doLog( $log_prepend . "View Translation: " . var_export($matches[0]['translation'], true) );
                 */
             } else {
                 Log::doLog($log_prepend . 'Realignment Failed. Skip. Segment: ' . $this->__postInput['id_segment']);
             }
         }
     }
     /* New Feature only if this is not a MT and if it is a ( 90 =< MATCH < 100 ) */
     if (!$this->concordance_search) {
         //execute these lines only in segment contribution search,
         //in case of user concordance search skip these lines
         $res = $this->setSuggestionReport($matches);
         if (is_array($res) and array_key_exists("error", $res)) {
             // error occurred
         }
         //
     }
     foreach ($matches as &$match) {
         if (strpos($match['created_by'], 'MT') !== false) {
             $match['match'] = 'MT';
             $QA = new PostProcess($match['raw_segment'], $match['raw_translation']);
             $QA->realignMTSpaces();
             //this should every time be ok because MT preserve tags, but we use the check on the errors
             //for logic correctness
             if (!$QA->thereAreErrors()) {
                 $match['raw_translation'] = $QA->getTrgNormalized();
                 $match['translation'] = CatUtils::rawxliff2view($match['raw_translation']);
             } else {
                 Log::doLog($QA->getErrors());
             }
         }
         if ($match['created_by'] == 'MT!') {
             $match['created_by'] = 'MT';
             //MyMemory returns MT!
         } else {
             $match['created_by'] = $this->__changeSuggestionSource($match);
         }
         if (!empty($match['sentence_confidence'])) {
             $match['sentence_confidence'] = round($match['sentence_confidence'], 0) . "%";
         }
         if ($this->concordance_search) {
             $match['segment'] = strip_tags(html_entity_decode($match['segment']));
             $match['segment'] = preg_replace('#[\\x{20}]{2,}#u', chr(0x20), $match['segment']);
             //Do something with &$match, tokenize strings and send to client
             $match['segment'] = preg_replace(array_keys($regularExpressions), array_values($regularExpressions), $match['segment']);
             $match['translation'] = strip_tags(html_entity_decode($match['translation']));
         }
     }
     $this->result['data']['matches'] = $matches;
 }
 public function doAction()
 {
     //get job language and data
     //Fixed Bug: need a specific job, because we need The target Language
     //Removed from within the foreach cycle, the job is always the same....
     $jobData = $this->jobInfo = getJobData($this->id_job, $this->password);
     $pCheck = new AjaxPasswordCheck();
     //check for Password correctness
     if (empty($jobData) || !$pCheck->grantJobAccessByJobData($jobData, $this->password)) {
         $msg = "Error : wrong password provided for download \n\n " . var_export($_POST, true) . "\n";
         Log::doLog($msg);
         Utils::sendErrMailReport($msg);
         return null;
     }
     //get storage object
     $fs = new FilesStorage();
     $files_job = $fs->getFilesForJob($this->id_job, $this->id_file);
     $nonew = 0;
     $output_content = array();
     /*
       the procedure:
       1)original xliff file is read directly from disk; a file handler is obtained
       2)the file is read chunk by chunk by a stream parser: for each trans-unit that is encountered, target is replaced (or added) with the corresponding translation obtained from the DB
       3)the parsed portion of xliff in the buffer is flushed on temporary file
       4)the temporary file is sent to the converter and an original file is obtained
       5)the temporary file is deleted
     */
     // This array will contain all the files of $files_job split by
     // converter version.
     $files_job_by_converter_version = array();
     // Detect the converter's version to use for each file, then store
     // file info accordingly.
     foreach ($files_job as $file) {
         $fileType = DetectProprietaryXliff::getInfo($file['xliffFilePath']);
         $files_job_by_converter_version[$fileType['converter_version']][] = $file;
     }
     // Process files according to the converters' versions, one version
     // at a time
     foreach ($files_job_by_converter_version as $converter_version => $files_job) {
         //file array is chuncked. Each chunk will be used for a parallel conversion request.
         $files_job = array_chunk($files_job, self::FILES_CHUNK_SIZE);
         foreach ($files_job as $chunk) {
             $converter = new FileFormatConverter($converter_version);
             $files_to_be_converted = array();
             foreach ($chunk as $file) {
                 $mime_type = $file['mime_type'];
                 $fileID = $file['id_file'];
                 $current_filename = $file['filename'];
                 //get path for the output file converted to know it's right extension
                 $_fileName = explode(DIRECTORY_SEPARATOR, $file['xliffFilePath']);
                 $outputPath = INIT::$TMP_DOWNLOAD . '/' . $this->id_job . '/' . $fileID . '/' . uniqid('', true) . "_.out." . array_pop($_fileName);
                 //make dir if doesn't exist
                 if (!file_exists(dirname($outputPath))) {
                     Log::doLog('Create Directory ' . escapeshellarg(dirname($outputPath)) . '');
                     mkdir(dirname($outputPath), 0775, true);
                 }
                 $data = getSegmentsDownload($this->id_job, $this->password, $fileID, $nonew);
                 //prepare regexp for nest step
                 $regexpEntity = '/&#x(0[0-8BCEF]|1[0-9A-F]|7F);/u';
                 $regexpAscii = '/([\\x{00}-\\x{1F}\\x{7F}]{1})/u';
                 foreach ($data as $i => $k) {
                     //create a secondary indexing mechanism on segments' array; this will be useful
                     //prepend a string so non-trans unit id ( ex: numerical ) are not overwritten
                     $data['matecat|' . $k['internal_id']][] = $i;
                     //FIXME: temporary patch
                     $data[$i]['translation'] = str_replace('<x id="nbsp"/>', '&#xA0;', $data[$i]['translation']);
                     $data[$i]['segment'] = str_replace('<x id="nbsp"/>', '&#xA0;', $data[$i]['segment']);
                     //remove binary chars in some xliff files
                     $sanitized_src = preg_replace($regexpAscii, '', $data[$i]['segment']);
                     $sanitized_trg = preg_replace($regexpAscii, '', $data[$i]['translation']);
                     //clean invalid xml entities ( charactes with ascii < 32 and different from 0A, 0D and 09
                     $sanitized_src = preg_replace($regexpEntity, '', $sanitized_src);
                     $sanitized_trg = preg_replace($regexpEntity, '', $sanitized_trg);
                     if ($sanitized_src != null) {
                         $data[$i]['segment'] = $sanitized_src;
                     }
                     if ($sanitized_trg != null) {
                         $data[$i]['translation'] = $sanitized_trg;
                     }
                 }
                 //instatiate parser
                 $xsp = new SdlXliffSAXTranslationReplacer($file['xliffFilePath'], $data, Langs_Languages::getInstance()->getLangRegionCode($jobData['target']), $outputPath);
                 if ($this->download_type == 'omegat') {
                     $xsp->setSourceInTarget(true);
                 }
                 //run parsing
                 Log::doLog("work on " . $fileID . " " . $current_filename);
                 $xsp->replaceTranslation();
                 //free memory
                 unset($xsp);
                 unset($data);
                 $output_content[$fileID]['document_content'] = file_get_contents($outputPath);
                 $output_content[$fileID]['output_filename'] = $current_filename;
                 $fileType = DetectProprietaryXliff::getInfo($file['xliffFilePath']);
                 if ($this->forceXliff) {
                     //clean the output filename by removing
                     // the unique hash identifier 55e5739b467109.05614837_.out.Test_English.doc.sdlxliff
                     $output_content[$fileID]['output_filename'] = preg_replace('#[0-9a-f]+\\.[0-9_]+\\.out\\.#i', '', FilesStorage::basename_fix($outputPath));
                     if ($fileType['proprietary_short_name'] === 'matecat_converter') {
                         // Set the XLIFF extension to .xlf
                         // Internally, MateCat continues using .sdlxliff as default
                         // extension for the XLIFF behind the projects.
                         // Changing this behavior requires a huge refactoring that
                         // it's scheduled for future versions.
                         // We quickly fixed the behaviour from the user standpoint
                         // using the following line of code, that changes the XLIFF's
                         // extension just a moment before it is downloaded by the user.
                         $output_content[$fileID]['output_filename'] = preg_replace("|\\.sdlxliff\$|i", ".xlf", $output_content[$fileID]['output_filename']);
                     }
                 }
                 /**
                  * Conversion Enforce
                  */
                 $convertBackToOriginal = true;
                 //if it is a not converted file ( sdlxliff ) we have originalFile equals to xliffFile (it has just been copied)
                 $file['original_file'] = file_get_contents($file['originalFilePath']);
                 // When the 'proprietary' flag is set to false, the xliff
                 // is not passed to any converter, because is handled
                 // directly inside MateCAT.
                 $xliffWasNotConverted = $fileType['proprietary'] === false;
                 if (!INIT::$CONVERSION_ENABLED || ($file['originalFilePath'] == $file['xliffFilePath'] and $xliffWasNotConverted) or $this->forceXliff) {
                     $convertBackToOriginal = false;
                     Log::doLog("SDLXLIFF: {$file['filename']} --- " . var_export($convertBackToOriginal, true));
                 } else {
                     //TODO: dos2unix ??? why??
                     //force unix type files
                     Log::doLog("NO SDLXLIFF, Conversion enforced: {$file['filename']} --- " . var_export($convertBackToOriginal, true));
                 }
                 if ($convertBackToOriginal) {
                     $output_content[$fileID]['out_xliff_name'] = $outputPath;
                     $output_content[$fileID]['source'] = $jobData['source'];
                     $output_content[$fileID]['target'] = $jobData['target'];
                     $files_to_be_converted[$fileID] = $output_content[$fileID];
                 } elseif ($this->forceXliff) {
                     $this->cleanFilePath($output_content[$fileID]['document_content']);
                 }
             }
             $convertResult = $converter->multiConvertToOriginal($files_to_be_converted, $chosen_machine = false);
             foreach (array_keys($files_to_be_converted) as $fileID) {
                 $output_content[$fileID]['document_content'] = $this->ifGlobalSightXliffRemoveTargetMarks($convertResult[$fileID]['document_content'], $files_to_be_converted[$fileID]['output_filename']);
                 //in case of .strings, they are required to be in UTF-16
                 //get extension to perform file detection
                 $extension = FilesStorage::pathinfo_fix($output_content[$fileID]['output_filename'], PATHINFO_EXTENSION);
                 if (strtoupper($extension) == 'STRINGS') {
                     //use this function to convert stuff
                     $encodingConvertedFile = CatUtils::convertEncoding('UTF-16', $output_content[$fileID]['document_content']);
                     //strip previously added BOM
                     $encodingConvertedFile[1] = $converter->stripBOM($encodingConvertedFile[1], 16);
                     //store new content
                     $output_content[$fileID]['document_content'] = $encodingConvertedFile[1];
                     //trash temporary data
                     unset($encodingConvertedFile);
                 }
             }
             unset($convertResult);
         }
     }
     foreach ($output_content as $idFile => $fileInformations) {
         $zipPathInfo = ZipArchiveExtended::zipPathInfo($output_content[$idFile]['output_filename']);
         if (is_array($zipPathInfo)) {
             $output_content[$idFile]['zipfilename'] = $zipPathInfo['zipfilename'];
             $output_content[$idFile]['zipinternalPath'] = $zipPathInfo['dirname'];
             $output_content[$idFile]['output_filename'] = $zipPathInfo['basename'];
         }
     }
     //set the file Name
     $pathinfo = FilesStorage::pathinfo_fix($this->fname);
     $this->_filename = $pathinfo['filename'] . "_" . $jobData['target'] . "." . $pathinfo['extension'];
     //qui prodest to check download type?
     if ($this->download_type == 'omegat') {
         $this->_filename .= ".zip";
         $tmsService = new TMSService();
         $tmsService->setOutputType('tm');
         /**
          * @var $tmFile SplTempFileObject
          */
         $tmFile = $tmsService->exportJobAsTMX($this->id_job, $this->password, $jobData['source'], $jobData['target']);
         $tmsService->setOutputType('mt');
         /**
          * @var $mtFile SplTempFileObject
          */
         $mtFile = $tmsService->exportJobAsTMX($this->id_job, $this->password, $jobData['source'], $jobData['target']);
         $tm_id = uniqid('tm');
         $mt_id = uniqid('mt');
         $output_content[$tm_id] = array('document_content' => '', 'output_filename' => $pathinfo['filename'] . "_" . $jobData['target'] . "_TM . tmx");
         foreach ($tmFile as $lineNumber => $content) {
             $output_content[$tm_id]['document_content'] .= $content;
         }
         $output_content[$mt_id] = array('document_content' => '', 'output_filename' => $pathinfo['filename'] . "_" . $jobData['target'] . "_MT . tmx");
         foreach ($mtFile as $lineNumber => $content) {
             $output_content[$mt_id]['document_content'] .= $content;
         }
         $this->createOmegaTZip($output_content, $jobData['source'], $jobData['target']);
         //add zip archive content here;
     } else {
         try {
             $output_content = $this->getOutputContentsWithZipFiles($output_content);
             if (count($output_content) > 1) {
                 //cast $output_content elements to ZipContentObject
                 foreach ($output_content as $key => $__output_content_elem) {
                     $output_content[$key] = new ZipContentObject($__output_content_elem);
                 }
                 if ($pathinfo['extension'] != 'zip') {
                     if ($this->forceXliff) {
                         $this->_filename = $this->id_job . ".zip";
                     } else {
                         $this->_filename = $pathinfo['basename'] . ".zip";
                     }
                 }
                 $this->content = self::composeZip($output_content);
                 //add zip archive content here;
             } else {
                 //always an array with 1 element, pop it, Ex: array( array() )
                 $output_content = array_pop($output_content);
                 $this->setContent($output_content);
             }
         } catch (Exception $e) {
             $msg = "\n\n Error retrieving file content, Conversion failed??? \n\n Error: {$e->getMessage()} \n\n" . var_export($e->getTraceAsString(), true);
             $msg .= "\n\n Request: " . var_export($_REQUEST, true);
             Log::$fileName = 'fatal_errors.txt';
             Log::doLog($msg);
             Utils::sendErrMailReport($msg);
             $this->unlockToken(array("code" => -110, "message" => "Download failed. Please contact " . INIT::$SUPPORT_MAIL));
             throw $e;
             // avoid sent Headers and empty file content with finalize method
         }
     }
     try {
         Utils::deleteDir(INIT::$TMP_DOWNLOAD . '/' . $this->id_job . '/');
     } catch (Exception $e) {
         Log::doLog('Failed to delete dir:' . $e->getMessage());
     }
 }
 /**
  * When Called it perform the controller action to retrieve/manipulate data
  *
  * @throws Exception
  */
 public function doAction()
 {
     if (!empty($this->result['errors'])) {
         return;
     }
     $job_data = getJobData((int) $this->id_job, $this->password_job);
     if (empty($job_data)) {
         $msg = "Error : empty job data \n\n " . var_export($_POST, true) . "\n";
         Log::doLog($msg);
         Utils::sendErrMailReport($msg);
     }
     //add check for job status archived.
     if (strtolower($job_data['status']) == Constants_JobStatus::STATUS_ARCHIVED) {
         $this->result['errors'][] = array("code" => -6, "message" => "job archived");
     }
     $this->parseIDSegment();
     $pCheck = new AjaxPasswordCheck();
     //check for Password correctness
     if (empty($job_data) || !$pCheck->grantJobAccessByJobData($job_data, $this->password_job, $this->id_segment)) {
         $this->result['errors'][] = array("code" => -7, "message" => "wrong password");
     }
     $wStruct = new WordCount_Struct();
     $wStruct->setIdJob($this->id_job);
     $wStruct->setJobPassword($this->password_job);
     $wStruct->setNewWords($job_data['new_words']);
     $wStruct->setDraftWords($job_data['draft_words']);
     $wStruct->setTranslatedWords($job_data['translated_words']);
     $wStruct->setApprovedWords($job_data['approved_words']);
     $wStruct->setRejectedWords($job_data['rejected_words']);
     $reviseDAO = new Revise_ReviseDAO(Database::obtain());
     //store segment revision in DB
     $revisionStruct = Revise_ReviseStruct::getStruct();
     $revisionStruct->id_job = $this->id_job;
     $revisionStruct->id_segment = $this->id_segment;
     //check if an old revision exists. If it does, retrieve it and save it.
     $oldRevision = $reviseDAO->read($revisionStruct);
     $oldRevision = isset($oldRevision[0]) ? $oldRevision[0] : Revise_ReviseStruct::setDefaultValues(Revise_ReviseStruct::getStruct());
     $revisionStruct->err_typing = $this->err_typing;
     $revisionStruct->err_translation = $this->err_translation;
     $revisionStruct->err_terminology = $this->err_terminology;
     $revisionStruct->err_language = $this->err_language;
     $revisionStruct->err_style = $this->err_style;
     $revisionStruct->original_translation = $this->original_translation;
     //save the new revision in the database.
     try {
         $reviseDAO->create($revisionStruct);
     } catch (Exception $e) {
         Log::doLog(__METHOD__ . " -> " . $e->getMessage());
         $this->result['errors'][] = array('code' => -4, 'message' => "Insert failed");
         return;
     }
     /**
      * Refresh error counters in the job table
      */
     $errorCountStruct = new ErrorCount_DiffStruct($oldRevision, $revisionStruct);
     $errorCountStruct->setIdJob($this->id_job);
     $errorCountStruct->setJobPassword($this->password_job);
     $errorCountDao = new ErrorCount_ErrorCountDAO(Database::obtain());
     try {
         $errorCountDao->update($errorCountStruct);
     } catch (Exception $e) {
         Log::doLog(__METHOD__ . " -> " . $e->getMessage());
         $this->result['errors'][] = array('code' => -5, 'message' => "Did not update job error counters.");
         return;
     }
     /**
      * Retrieve information about job errors
      * ( Note: these information are fed by the revision process )
      * @see setRevisionController
      */
     $jobQA = new Revise_JobQA($this->id_job, $this->password_job, $wStruct->getTotal());
     $jobQA->retrieveJobErrorTotals();
     $jobVote = $jobQA->evalJobVote();
     $this->result['data']['message'] = 'OK';
     $this->result['data']['stat_quality'] = $jobQA->getQaData();
     $this->result['data']['overall_quality'] = $jobVote['minText'];
     $this->result['data']['overall_quality_class'] = strtolower(str_replace(' ', '', $jobVote['minText']));
 }
 public function doAction()
 {
     $debug = array();
     $debug['total'][] = time();
     //get job language and data
     //Fixed Bug: need a specific job, because we need The target Language
     //Removed from within the foreach cycle, the job is always the same....
     $jobData = $this->jobInfo = getJobData($this->id_job, $this->password);
     $pCheck = new AjaxPasswordCheck();
     //check for Password correctness
     if (empty($jobData) || !$pCheck->grantJobAccessByJobData($jobData, $this->password)) {
         $msg = "Error : wrong password provided for download \n\n " . var_export($_POST, true) . "\n";
         Log::doLog($msg);
         Utils::sendErrMailReport($msg);
         return null;
     }
     $debug['get_file'][] = time();
     $files_job = getFilesForJob($this->id_job, $this->id_file);
     $debug['get_file'][] = time();
     $nonew = 0;
     $output_content = array();
     /*
      * the procedure is now as follows:
      * 1)original file is loaded from DB into RAM and the flushed in a temp file on disk; a file handler is obtained
      * 2)RAM gets freed from original content
      * 3)the file is read chunk by chunk by a stream parser: for each tran-unit that is encountered,
      *     target is replaced (or added) with the corresponding translation among segments
      *     the current string in the buffer is flushed on standard output
      * 4)the temporary file is deleted by another process after some time
      *
      */
     //file array is chuncked. Each chunk will be used for a parallel conversion request.
     $files_job = array_chunk($files_job, self::FILES_CHUNK_SIZE);
     foreach ($files_job as $chunk) {
         $converter = new FileFormatConverter();
         $files_buffer = array();
         foreach ($chunk as $file) {
             $mime_type = $file['mime_type'];
             $fileID = $file['id_file'];
             $current_filename = $file['filename'];
             $original_xliff = $file['xliff_file'];
             //get path
             $path = INIT::$TMP_DOWNLOAD . '/' . $this->id_job . '/' . $fileID . '/' . $current_filename . "_" . uniqid('', true) . '.sdlxliff';
             //make dir if doesn't exist
             if (!file_exists(dirname($path))) {
                 Log::doLog('exec ("chmod 666 ' . escapeshellarg($path) . '");');
                 mkdir(dirname($path), 0777, true);
                 exec("chmod 666 " . escapeshellarg($path));
             }
             //create file
             $fp = fopen($path, 'w+');
             //flush file to disk
             fwrite($fp, $original_xliff);
             //free memory, as we can work with file on disk now
             unset($original_xliff);
             $debug['get_segments'][] = time();
             $data = getSegmentsDownload($this->id_job, $this->password, $fileID, $nonew);
             $debug['get_segments'][] = time();
             //create a secondary indexing mechanism on segments' array; this will be useful
             //prepend a string so non-trans unit id ( ex: numerical ) are not overwritten
             //clean also not valid xml entities ( charactes with ascii < 32 and different from 0A, 0D and 09
             $regexpEntity = '/&#x(0[0-8BCEF]|1[0-9A-F]|7F);/u';
             //remove binary chars in some xliff files
             $regexpAscii = '/([\\x{00}-\\x{1F}\\x{7F}]{1})/u';
             foreach ($data as $i => $k) {
                 $data['matecat|' . $k['internal_id']][] = $i;
                 //FIXME: temporary patch
                 $data[$i]['translation'] = str_replace('<x id="nbsp"/>', '&#xA0;', $data[$i]['translation']);
                 $data[$i]['segment'] = str_replace('<x id="nbsp"/>', '&#xA0;', $data[$i]['segment']);
                 $sanitized_src = preg_replace($regexpAscii, '', $data[$i]['segment']);
                 $sanitized_trg = preg_replace($regexpAscii, '', $data[$i]['translation']);
                 $sanitized_src = preg_replace($regexpEntity, '', $sanitized_src);
                 $sanitized_trg = preg_replace($regexpEntity, '', $sanitized_trg);
                 if ($sanitized_src != null) {
                     $data[$i]['segment'] = $sanitized_src;
                 }
                 if ($sanitized_trg != null) {
                     $data[$i]['translation'] = $sanitized_trg;
                 }
             }
             $debug['replace'][] = time();
             //instatiate parser
             $xsp = new XliffSAXTranslationReplacer($path, $data, Langs_Languages::getInstance()->getLangRegionCode($jobData['target']), $fp);
             if ($this->download_type == 'omegat') {
                 $xsp->setSourceInTarget(true);
             }
             //run parsing
             Log::doLog("work on " . $fileID . " " . $current_filename);
             $xsp->replaceTranslation();
             fclose($fp);
             unset($xsp);
             $debug['replace'][] = time();
             $output_xliff = file_get_contents($path . '.out.sdlxliff');
             $output_content[$fileID]['documentContent'] = $output_xliff;
             $output_content[$fileID]['filename'] = $current_filename;
             unset($output_xliff);
             if ($this->forceXliff) {
                 $file_info_details = pathinfo($output_content[$fileID]['filename']);
                 $output_content[$fileID]['filename'] = $file_info_details['filename'] . ".out.sdlxliff";
             }
             //TODO set a flag in database when file uploaded to know if this file is a proprietary xlf converted
             //TODO so we can load from database the original file blob ONLY when needed
             /**
              * Conversion Enforce
              */
             $convertBackToOriginal = true;
             try {
                 //if it is a not converted file ( sdlxliff ) we have an empty field original_file
                 //so we can simplify all the logic with:
                 // is empty original_file? if it is, we don't need conversion back because
                 // we already have an sdlxliff or an accepted file
                 $file['original_file'] = @gzinflate($file['original_file']);
                 if (!INIT::$CONVERSION_ENABLED || empty($file['original_file']) && $mime_type == 'sdlxliff' || $this->forceXliff) {
                     $convertBackToOriginal = false;
                     Log::doLog("SDLXLIFF: {$file['filename']} --- " . var_export($convertBackToOriginal, true));
                 } else {
                     //TODO: dos2unix ??? why??
                     //force unix type files
                     Log::doLog("NO SDLXLIFF, Conversion enforced: {$file['filename']} --- " . var_export($convertBackToOriginal, true));
                 }
             } catch (Exception $e) {
                 Log::doLog($e->getMessage());
             }
             if ($convertBackToOriginal) {
                 $output_content[$fileID]['out_xliff_name'] = $path . '.out.sdlxliff';
                 $output_content[$fileID]['source'] = $jobData['source'];
                 $output_content[$fileID]['target'] = $jobData['target'];
                 $files_buffer[$fileID] = $output_content[$fileID];
             } elseif ($this->forceXliff) {
                 $this->cleanFilePath($output_content[$fileID]['documentContent']);
             }
         }
         $debug['do_conversion'][] = time();
         $convertResult = $converter->multiConvertToOriginal($files_buffer, $chosen_machine = false);
         foreach (array_keys($files_buffer) as $fileID) {
             $output_content[$fileID]['documentContent'] = $this->removeTargetMarks($convertResult[$fileID]['documentContent'], $files_buffer[$fileID]['filename']);
             //in case of .strings, they are required to be in UTF-16
             //get extension to perform file detection
             $extension = pathinfo($output_content[$fileID]['filename'], PATHINFO_EXTENSION);
             if (strtoupper($extension) == 'STRINGS') {
                 //use this function to convert stuff
                 $encodingConvertedFile = CatUtils::convertEncoding('UTF-16', $output_content[$fileID]['documentContent']);
                 //strip previously added BOM
                 $encodingConvertedFile[1] = $converter->stripBOM($encodingConvertedFile[1], 16);
                 //store new content
                 $output_content[$fileID]['documentContent'] = $encodingConvertedFile[1];
                 //trash temporary data
                 unset($encodingConvertedFile);
             }
         }
         //            $output_content[ $fileID ][ 'documentContent' ] = $convertResult[ 'documentContent' ];
         unset($convertResult);
         $debug['do_conversion'][] = time();
     }
     //set the file Name
     $pathinfo = pathinfo($this->fname);
     $this->filename = $pathinfo['filename'] . "_" . $jobData['target'] . "." . $pathinfo['extension'];
     //qui prodest to check download type?
     if ($this->download_type == 'omegat') {
         $this->filename .= ".zip";
         $tmsService = new TMSService();
         $tmsService->setOutputType('tm');
         /**
          * @var $tmFile SplTempFileObject
          */
         $tmFile = $tmsService->exportJobAsTMX($this->id_job, $this->password, $jobData['source'], $jobData['target']);
         $tmsService->setOutputType('mt');
         /**
          * @var $mtFile SplTempFileObject
          */
         $mtFile = $tmsService->exportJobAsTMX($this->id_job, $this->password, $jobData['source'], $jobData['target']);
         $tm_id = uniqid('tm');
         $mt_id = uniqid('mt');
         $output_content[$tm_id] = array('documentContent' => '', 'filename' => $pathinfo['filename'] . "_" . $jobData['target'] . "_TM . tmx");
         foreach ($tmFile as $lineNumber => $content) {
             $output_content[$tm_id]['documentContent'] .= $content;
         }
         $output_content[$mt_id] = array('documentContent' => '', 'filename' => $pathinfo['filename'] . "_" . $jobData['target'] . "_MT . tmx");
         foreach ($mtFile as $lineNumber => $content) {
             $output_content[$mt_id]['documentContent'] .= $content;
         }
         $this->createOmegaTZip($output_content, $jobData['source'], $jobData['target']);
         //add zip archive content here;
     } else {
         if (count($output_content) > 1) {
             if ($pathinfo['extension'] != 'zip') {
                 if ($this->forceXliff) {
                     $this->filename = $this->id_job . ".zip";
                 } else {
                     $this->filename = $pathinfo['basename'] . ".zip";
                 }
             }
             $this->composeZip($output_content, $jobData['source']);
             //add zip archive content here;
         } else {
             //always an array with 1 element, pop it, Ex: array( array() )
             $output_content = array_pop($output_content);
             $this->setContent($output_content);
         }
     }
     $debug['total'][] = time();
     Utils::deleteDir(INIT::$TMP_DOWNLOAD . '/' . $this->id_job . '/');
 }
 public function doAction()
 {
     if (is_null($this->source) || $this->source === '') {
         $this->result['errors'][] = array("code" => -1, "message" => "missing source segment");
     }
     if (is_null($this->target) || $this->target === '') {
         $this->result['errors'][] = array("code" => -2, "message" => "missing target segment");
     }
     if (empty($this->source_lang)) {
         $this->result['errors'][] = array("code" => -3, "message" => "missing source lang");
     }
     if (empty($this->target_lang)) {
         $this->result['errors'][] = array("code" => -2, "message" => "missing target lang");
     }
     if (empty($this->id_job)) {
         $this->result['errors'][] = array("code" => -4, "message" => "id_job not valid");
         $msg = "\n\n Critical. Quit. \n\n " . var_export(array_merge($this->result, $_POST), true);
         Log::doLog($msg);
         Utils::sendErrMailReport($msg);
         // critical. Quit.
         return -1;
     }
     //get Job Infos, we need only a row of jobs ( split )
     $job_data = getJobData((int) $this->id_job, $this->password);
     $pCheck = new AjaxPasswordCheck();
     //check for Password correctness
     if (empty($job_data)) {
         $this->result['errors'][] = array("code" => -101, "message" => "error fetching job data");
     }
     if (empty($this->result['errors']) && !$pCheck->grantJobAccessByJobData($job_data, $this->password)) {
         $this->result['errors'][] = array("code" => -10, "message" => "wrong password");
     }
     if (!empty($this->result['errors'])) {
         $msg = "\n\n Error \n\n " . var_export(array_merge($this->result, $_POST), true);
         Log::doLog($msg);
         Utils::sendErrMailReport($msg);
         return -1;
     }
     $id_tms = $job_data['id_tms'];
     $tm_keys = $job_data['tm_keys'];
     if ($id_tms != 0) {
         $tms = Engine::getInstance(1);
         /**
          * @var $tms Engines_MyMemory
          */
         $config = $tms->getConfigStruct();
         $config['segment'] = CatUtils::view2rawxliff($this->source);
         $config['translation'] = CatUtils::view2rawxliff($this->target);
         $config['source'] = $this->source_lang;
         $config['target'] = $this->target_lang;
         $config['email'] = "*****@*****.**";
         //Props
         $config['prop'] = json_encode(CatUtils::getTMProps($job_data));
         //instantiate TMS object
         $result = array();
         $this->checkLogin();
         try {
             if (self::isRevision()) {
                 $this->userRole = TmKeyManagement_Filter::ROLE_REVISOR;
             }
             //find all the job's TMs with write grants and make a contribution to them
             $tm_keys = TmKeyManagement_TmKeyManagement::getJobTmKeys($tm_keys, 'w', 'tm', $this->uid, $this->userRole);
             if (!empty($tm_keys)) {
                 unset($config['id_user']);
                 foreach ($tm_keys as $i => $tm_info) {
                     $config['id_user'] = $tm_info->key;
                     $res = $tms->set($config);
                     if (!$res) {
                         $result[] = $res;
                         $this->result['errors'][] = array("code" => -5, "message" => "Set contribution error for key " . $tm_info->name);
                     }
                 }
             } else {
                 $res = $tms->set($config);
                 if (!$res) {
                     $result[] = $res;
                     $this->result['errors'][] = array("code" => -5, "message" => "Set contribution error");
                 }
             }
         } catch (Exception $e) {
             $this->result['errors'][] = array("code" => -6, "message" => "Error while retrieving job's TM.");
             Log::doLog(__METHOD__ . " -> " . $e->getMessage());
         }
         //if translator_username is empty no key is added to MyMemory API SET query string, so, anonymous by default
         if (count($result)) {
             $this->result['code'] = -1;
             $this->result['data'] = "KO";
             Log::doLog("Set Contribution Failed.");
             Log::doLog(var_export($_POST, true));
             return -1;
         }
         $this->result['code'] = 1;
         $this->result['data'] = "OK";
     } else {
         $this->result['code'] = 1;
         $this->result['data'] = "NOCONTRIB_OK";
     }
 }
 public function doAction()
 {
     $this->parseIDSegment();
     //get Job Infos
     $job_data = getJobData((int) $this->id_job);
     $pCheck = new AjaxPasswordCheck();
     if (!$pCheck->grantJobAccessByJobData($job_data, $this->password)) {
         $this->result['errors'][] = array("code" => -10, "message" => "wrong password");
     }
     if (empty($this->id_segment)) {
         $this->result['errors'][] = array("code" => -1, "message" => "missing segment id");
     }
     if (empty($this->id_job)) {
         $this->result['errors'][] = array("code" => -2, "message" => "missing Job id");
     }
     if (!empty($this->result['errors'])) {
         //no action on errors
         return;
     }
     $segmentStruct = TranslationsSplit_SplitStruct::getStruct();
     $segmentStruct->id_segment = $this->id_segment;
     $segmentStruct->id_job = $this->id_job;
     $translationDao = new TranslationsSplit_SplitDAO(Database::obtain());
     $currSegmentInfo = $translationDao->read($segmentStruct);
     /**
      * Split check control
      */
     $isASplittedSegment = false;
     $isLastSegmentChunk = true;
     if (count($currSegmentInfo) > 0) {
         $isASplittedSegment = true;
         $currSegmentInfo = array_shift($currSegmentInfo);
         //get the chunk number and check whether it is the last one or not
         $isLastSegmentChunk = $this->split_num == count($currSegmentInfo->source_chunk_lengths) - 1;
         if (!$isLastSegmentChunk) {
             $nextSegmentId = $this->id_segment . "-" . ($this->split_num + 1);
         }
     }
     /**
      * End Split check control
      */
     if (!$isASplittedSegment || $isLastSegmentChunk) {
         $segmentList = getNextSegment($this->id_segment, $this->id_job, $this->password, !self::isRevision() ? false : true);
         if (!self::isRevision()) {
             $nextSegmentId = fetchStatus($this->id_segment, $segmentList);
         } else {
             $nextSegmentId = fetchStatus($this->id_segment, $segmentList, Constants_TranslationStatus::STATUS_TRANSLATED);
             if (!$nextSegmentId) {
                 $nextSegmentId = fetchStatus($this->id_segment, $segmentList, Constants_TranslationStatus::STATUS_APPROVED);
             }
         }
     }
     $insertRes = setCurrentSegmentInsert($this->id_segment, $this->id_job, $this->password);
     $this->result['code'] = 1;
     $this->result['data'] = array();
     //get segment revision informations
     $reviseDao = new Revise_ReviseDAO(Database::obtain());
     $searchReviseStruct = Revise_ReviseStruct::getStruct();
     $searchReviseStruct->id_job = $this->id_job;
     $searchReviseStruct->id_segment = $this->id_segment;
     $_dbReviseStruct = $reviseDao->read($searchReviseStruct);
     if (count($_dbReviseStruct) > 0) {
         $_dbReviseStruct = $_dbReviseStruct[0];
     } else {
         $_dbReviseStruct = Revise_ReviseStruct::getStruct();
     }
     $_dbReviseStruct = Revise_ReviseStruct::setDefaultValues($_dbReviseStruct);
     $dbReviseStruct = self::prepareReviseStructReturnValues($_dbReviseStruct);
     $this->result['nextSegmentId'] = $nextSegmentId;
     $this->result['error_data'] = $dbReviseStruct;
     $this->result['original'] = CatUtils::rawxliff2view($_dbReviseStruct->original_translation);
 }
 public function doAction()
 {
     if (empty($this->source_lang)) {
         $this->result['errors'][] = array("code" => -1, "message" => "missing source_lang");
     }
     if (empty($this->target_lang)) {
         $this->result['errors'][] = array("code" => -2, "message" => "missing target_lang");
     }
     if (empty($this->source)) {
         $this->result['errors'][] = array("code" => -3, "message" => "missing source");
     }
     if (empty($this->target)) {
         $this->result['errors'][] = array("code" => -4, "message" => "missing target");
     }
     //get Job Infos
     $job_data = getJobData((int) $this->id_job, $this->password);
     $pCheck = new AjaxPasswordCheck();
     //check for Password correctness
     if (empty($job_data) || !$pCheck->grantJobAccessByJobData($job_data, $this->password)) {
         $this->result['errors'][] = array("code" => -10, "message" => "wrong password");
         return;
     }
     $this->tm_keys = $job_data['tm_keys'];
     $this->checkLogin();
     $tms = Engine::getInstance($job_data['id_tms']);
     $config = $tms->getConfigStruct();
     //        $config = TMS::getConfigStruct();
     $config['segment'] = CatUtils::view2rawxliff($this->source);
     $config['translation'] = CatUtils::view2rawxliff($this->target);
     $config['source'] = $this->source_lang;
     $config['target'] = $this->target_lang;
     $config['email'] = "*****@*****.**";
     $config['id_user'] = array();
     //get job's TM keys
     try {
         $tm_keys = $this->tm_keys;
         if (self::isRevision()) {
             $this->userRole = TmKeyManagement_Filter::ROLE_REVISOR;
         } elseif ($this->userMail == $job_data['owner']) {
             $tm_keys = TmKeyManagement_TmKeyManagement::getOwnerKeys(array($tm_keys), 'r', 'tm');
             $tm_keys = json_encode($tm_keys);
         }
         //get TM keys with read grants
         $tm_keys = TmKeyManagement_TmKeyManagement::getJobTmKeys($tm_keys, 'r', 'tm', $this->uid, $this->userRole);
         if (is_array($tm_keys) && !empty($tm_keys)) {
             foreach ($tm_keys as $tm_key) {
                 $config['id_user'][] = $tm_key->key;
             }
         }
     } catch (Exception $e) {
         $this->result['errors'][] = array("code" => -11, "message" => "Cannot retrieve TM keys info.");
         return;
     }
     //prepare the errors report
     $set_code = array();
     /**
      * @var $tm_key TmKeyManagement_TmKeyStruct
      */
     //if there's no key
     if (empty($tm_keys)) {
         //try deleting anyway, it may be a public segment and it may work
         $TMS_RESULT = $tms->delete($config);
         $set_code[] = $TMS_RESULT;
     } else {
         //loop over the list of keys
         foreach ($tm_keys as $tm_key) {
             //issue a separate call for each key
             $config['id_user'] = $tm_key->key;
             $TMS_RESULT = $tms->delete($config);
             $set_code[] = $TMS_RESULT;
         }
     }
     $set_successful = true;
     if (array_search(false, $set_code, true)) {
         //There's an errors
         $set_successful = false;
     }
     $this->result['data'] = $set_successful ? "OK" : null;
     $this->result['code'] = $set_successful;
 }
 protected function checkSplitAccess()
 {
     $passCheck = new AjaxPasswordCheck();
     $access = $passCheck->grantProjectJobAccessOnJobPass($this->project_data, $this->project_pass, $this->job_pass);
     if (!$access) {
         throw new Exception("Wrong Password. Access denied", -10);
     }
 }