public function doAction()
 {
     if (!empty($this->result['errors'])) {
         return;
     }
     //save the 2 arrays in the DB
     $translationStruct = TranslationsSplit_SplitStruct::getStruct();
     $translationStruct->id_segment = $this->id_segment;
     $translationStruct->id_job = $this->id_job;
     list($this->segment, $translationStruct->source_chunk_lengths) = CatUtils::parseSegmentSplit(CatUtils::view2rawxliff($this->segment));
     /* Fill the statuses with DEFAULT DRAFT VALUES */
     $pieces = count($translationStruct->source_chunk_lengths) > 1 ? count($translationStruct->source_chunk_lengths) - 1 : 1;
     $translationStruct->target_chunk_lengths = array('len' => array(0), 'statuses' => array_fill(0, $pieces, Constants_TranslationStatus::STATUS_DRAFT));
     $translationDao = new TranslationsSplit_SplitDAO(Database::obtain());
     $result = $translationDao->update($translationStruct);
     if ($result instanceof TranslationsSplit_SplitStruct) {
         //return success
         $this->result['data'] = 'OK';
     } else {
         Log::doLog("Failed while splitting/merging segment.");
         Log::doLog($translationStruct);
     }
 }
 public function doAction()
 {
     try {
         $this->_checkData();
     } catch (Exception $e) {
         if ($e->getCode() == -1) {
             Utils::sendErrMailReport($e->getMessage());
         }
         Log::doLog($e->getMessage());
         return $e->getCode();
     }
     //check tag mismatch
     //get original source segment, first
     $segment = getSegment($this->id_segment);
     //compare segment-translation and get results
     $check = new QA($segment['segment'], $this->translation);
     $check->performConsistencyCheck();
     if ($check->thereAreWarnings()) {
         $err_json = $check->getWarningsJSON();
         $translation = $this->translation;
     } else {
         $err_json = '';
         $translation = $check->getTrgNormalized();
     }
     /*
      * begin stats counter
      *
      * It works good with default InnoDB Isolation level
      *
      * REPEATABLE-READ offering a row level lock for this id_segment
      *
      */
     $db = Database::obtain();
     $db->begin();
     $old_translation = getCurrentTranslation($this->id_job, $this->id_segment);
     //        $old_version = ( empty( $old_translation['translation_date'] ) ? '0' : date_create( $old_translation['translation_date'] )->getTimestamp() );
     //        if( $this->client_target_version != $old_version ){
     //            $this->result[ 'errors' ][ ] = array( "code" => -102, "message" => "Translation version mismatch" );
     //            $db->rollback();
     //            return false;
     //        }
     //if volume analysis is not enabled and no translation rows exists
     //create the row
     if (!INIT::$VOLUME_ANALYSIS_ENABLED && empty($old_translation['status'])) {
         $_Translation = array();
         $_Translation['id_segment'] = (int) $this->id_segment;
         $_Translation['id_job'] = (int) $this->id_job;
         $_Translation['status'] = Constants_TranslationStatus::STATUS_NEW;
         $_Translation['segment_hash'] = $segment['segment_hash'];
         $_Translation['translation'] = $segment['segment'];
         $_Translation['standard_word_count'] = $segment['raw_word_count'];
         $_Translation['serialized_errors_list'] = '';
         $_Translation['suggestion_position'] = 0;
         $_Translation['warning'] = false;
         $_Translation['translation_date'] = date("Y-m-d H:i:s");
         $res = addTranslation($_Translation);
         if ($res < 0) {
             $this->result['errors'][] = array("code" => -101, "message" => "database errors");
             $db->rollback();
             return $res;
         }
         /*
          * begin stats counter
          *
          */
         $old_translation = $_Translation;
     }
     $_Translation = array();
     $_Translation['id_segment'] = $this->id_segment;
     $_Translation['id_job'] = $this->id_job;
     $_Translation['status'] = $this->status;
     $_Translation['time_to_edit'] = $this->time_to_edit;
     $_Translation['translation'] = preg_replace('/[ \\t\\n\\r\\0\\x0A\\xA0]+$/u', '', $translation);
     $_Translation['serialized_errors_list'] = $err_json;
     $_Translation['suggestion_position'] = $this->chosen_suggestion_index;
     $_Translation['warning'] = $check->thereAreWarnings();
     $_Translation['translation_date'] = date("Y-m-d H:i:s");
     /**
      * when the status of the translation changes, the auto propagation flag
      * must be removed
      */
     if ($_Translation['translation'] != $old_translation['translation'] || $this->status == Constants_TranslationStatus::STATUS_TRANSLATED || $this->status == Constants_TranslationStatus::STATUS_APPROVED) {
         $_Translation['autopropagated_from'] = 'NULL';
     }
     $res = CatUtils::addSegmentTranslation($_Translation);
     if (!empty($res['errors'])) {
         $this->result['errors'] = $res['errors'];
         $msg = "\n\n Error addSegmentTranslation \n\n Database Error \n\n " . var_export(array_merge($this->result, $_POST), true);
         Log::doLog($msg);
         Utils::sendErrMailReport($msg);
         $db->rollback();
         return -1;
     }
     if (INIT::$DQF_ENABLED && !empty($this->jobData['dqf_key']) && $_Translation['status'] == Constants_TranslationStatus::STATUS_TRANSLATED) {
         $dqfSegmentStruct = DQF_DqfSegmentStruct::getStruct();
         if ($old_translation['suggestion'] == null) {
             $dqfSegmentStruct->target_segment = "";
             $dqfSegmentStruct->tm_match = 0;
         } else {
             $dqfSegmentStruct->target_segment = $old_translation['suggestion'];
             $dqfSegmentStruct->tm_match = $old_translation['suggestion_match'];
         }
         $dqfSegmentStruct->task_id = $this->id_job;
         $dqfSegmentStruct->segment_id = $this->id_segment;
         $dqfSegmentStruct->source_segment = $segment['segment'];
         $dqfSegmentStruct->new_target_segment = $_Translation['translation'];
         $dqfSegmentStruct->time = $_Translation['time_to_edit'];
         //            $dqfSegmentStruct->mtengine = $this->jobData['id_mt_engine'];
         $dqfSegmentStruct->mt_engine_version = 1;
         try {
             $dqfQueueHandler = new Analysis_DqfQueueHandler();
             $dqfQueueHandler->createSegment($dqfSegmentStruct);
         } catch (Exception $exn) {
             $msg = $exn->getMessage() . "\n\n" . $exn->getTraceAsString();
             Log::doLog($msg);
             Utils::sendErrMailReport($msg);
         }
     }
     $propagateToTranslated = true;
     //for the moment, this is set explicitely
     if ($this->propagate == false) {
         $propagateToTranslated = false;
     }
     //propagate translations
     $TPropagation = array();
     //Warning: this value will NOT be used to update values,
     //but to exclude current segment from auto-propagation
     $_idSegment = $this->id_segment;
     $propagateToTranslated ? $TPropagation['status'] = $this->status : null;
     $TPropagation['id_job'] = $this->id_job;
     $TPropagation['translation'] = $translation;
     $TPropagation['autopropagated_from'] = $this->id_segment;
     $TPropagation['serialized_errors_list'] = $err_json;
     $TPropagation['warning'] = $check->thereAreWarnings();
     //        $TPropagation[ 'translation_date' ]       = date( "Y-m-d H:i:s" );
     $TPropagation['segment_hash'] = $old_translation['segment_hash'];
     $propagationTotal = array();
     if ($propagateToTranslated && in_array($this->status, array(Constants_TranslationStatus::STATUS_TRANSLATED, Constants_TranslationStatus::STATUS_APPROVED, Constants_TranslationStatus::STATUS_REJECTED))) {
         try {
             $propagationTotal = propagateTranslation($TPropagation, $this->jobData, $_idSegment, $propagateToTranslated);
         } catch (Exception $e) {
             $msg = $e->getMessage() . "\n\n" . $e->getTraceAsString();
             Log::doLog($msg);
             Utils::sendErrMailReport($msg);
         }
     }
     //Recount Job Totals
     $old_wStruct = new WordCount_Struct();
     $old_wStruct->setIdJob($this->id_job);
     $old_wStruct->setJobPassword($this->password);
     $old_wStruct->setNewWords($this->jobData['new_words']);
     $old_wStruct->setDraftWords($this->jobData['draft_words']);
     $old_wStruct->setTranslatedWords($this->jobData['translated_words']);
     $old_wStruct->setApprovedWords($this->jobData['approved_words']);
     $old_wStruct->setRejectedWords($this->jobData['rejected_words']);
     $old_wStruct->setIdSegment($this->id_segment);
     //redundant, this is made into WordCount_Counter::updateDB
     $old_wStruct->setOldStatus($old_translation['status']);
     $old_wStruct->setNewStatus($this->status);
     //redundant because the update is made only where status = old status
     if ($this->status != $old_translation['status']) {
         //cambiato status, sposta i conteggi
         $old_count = !is_null($old_translation['eq_word_count']) ? $old_translation['eq_word_count'] : $segment['raw_word_count'];
         //if there is not a row in segment_translations because volume analysis is disabled
         //search for a just created row
         $old_status = !empty($old_translation['status']) ? $old_translation['status'] : Constants_TranslationStatus::STATUS_NEW;
         $counter = new WordCount_Counter($old_wStruct);
         $counter->setOldStatus($old_status);
         $counter->setNewStatus($this->status);
         $newValues = array();
         $newValues[] = $counter->getUpdatedValues($old_count);
         foreach ($propagationTotal as $__pos => $old_value) {
             $counter->setOldStatus($old_value['status']);
             $counter->setNewStatus($this->status);
             $newValues[] = $counter->getUpdatedValues($old_value['total']);
         }
         try {
             $newTotals = $counter->updateDB($newValues);
         } catch (Exception $e) {
             $this->result['errors'][] = array("code" => -101, "message" => "database errors");
             //                Log::doLog("Lock: Transaction Aborted. " . $e->getMessage() );
             //                $x1 = explode( "\n" , var_export( $old_translation, true) );
             //                Log::doLog("Lock: Translation status was " . implode( " ", $x1 ) );
             $db->rollback();
             return $e->getCode();
         }
     } else {
         $newTotals = $old_wStruct;
     }
     $job_stats = CatUtils::getFastStatsForJob($newTotals);
     $project = getProject($this->jobData['id_project']);
     $project = array_pop($project);
     $job_stats['ANALYSIS_COMPLETE'] = $project['status_analysis'] == Constants_ProjectStatus::STATUS_DONE || $project['status_analysis'] == Constants_ProjectStatus::STATUS_NOT_TO_ANALYZE ? true : false;
     $file_stats = array();
     $this->result['stats'] = $job_stats;
     $this->result['file_stats'] = $file_stats;
     $this->result['code'] = 1;
     $this->result['data'] = "OK";
     $this->result['version'] = date_create($_Translation['translation_date'])->getTimestamp();
     /* FIXME: added for code compatibility with front-end. Remove. */
     $_warn = $check->getWarnings();
     $warning = $_warn[0];
     /* */
     $this->result['warning']['cod'] = $warning->outcome;
     if ($warning->outcome > 0) {
         $this->result['warning']['id'] = $this->id_segment;
     } else {
         $this->result['warning']['id'] = 0;
     }
     //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)) {
         /* put the split inside the transaction if they are present */
         $translationStruct = TranslationsSplit_SplitStruct::getStruct();
         $translationStruct->id_segment = $this->id_segment;
         $translationStruct->id_job = $this->id_job;
         $translationStruct->target_chunk_lengths = array('len' => $this->split_chunk_lengths, 'statuses' => $this->split_statuses);
         $translationDao = new TranslationsSplit_SplitDAO(Database::obtain());
         $result = $translationDao->update($translationStruct);
     }
     $db->commit();
     if ($job_stats['TRANSLATED_PERC'] == '100') {
         $update_completed = setJobCompleteness($this->id_job, 1);
     }
     if (@$update_completed < 0) {
         $msg = "\n\n Error setJobCompleteness \n\n " . var_export($_POST, true);
         Log::doLog($msg);
         Utils::sendErrMailReport($msg);
     }
 }