/** * {@inheritdoc} */ public function checkoutSettingsForm(array $form, FormStateInterface $form_state, JobInterface $job) { if ($job->getTranslator()->getSetting('expose_settings')) { $form['action'] = array('#type' => 'select', '#title' => t('Action'), '#options' => array('translate' => t('Translate'), 'submit' => t('Submit'), 'reject' => t('Reject'), 'fail' => t('Fail'), 'not_available' => t('Not available'), 'not_translatable' => t('Not translatable')), '#default_value' => $job->getTranslator()->getSetting('action')); } return $form; }
/** * {@inheritdoc} */ public function checkoutInfo(JobInterface $job) { // If the job is finished, it's not possible to import translations anymore. if ($job->isFinished()) { return parent::checkoutInfo($job); } $form = array('#type' => 'fieldset', '#title' => t('Import translated file')); $supported_formats = array_keys(\Drupal::service('plugin.manager.tmgmt_file.format')->getDefinitions()); $form['file'] = array('#type' => 'file', '#title' => t('File'), '#size' => 50, '#description' => t('Supported formats: @formats.', array('@formats' => implode(', ', $supported_formats)))); $form['submit'] = array('#type' => 'submit', '#value' => t('Import'), '#submit' => array('tmgmt_file_import_form_submit')); return $this->checkoutInfoWrapper($job, $form); }
/** * Implements TMGMTFileExportInterface::export(). */ public function export(JobInterface $job, $conditions = array()) { $items = array(); foreach ($job->getItems($conditions) as $item) { $data = \Drupal::service('tmgmt.data')->filterTranslatable($item->getData()); foreach ($data as $key => $value) { $items[$item->id()][$this->encodeIdSafeBase64($item->id() . '][' . $key)] = $value; } } $elements = array('#theme' => 'tmgmt_file_html_template', '#tjid' => $job->id(), '#source_language' => $job->getRemoteSourceLanguage(), '#target_language' => $job->getRemoteTargetLanguage(), '#items' => $items); return \Drupal::service('renderer')->renderPlain($elements); }
/** * {@inheritdoc} */ public function checkoutInfo(JobInterface $job) { $tuid = $job->getSetting('translator'); if ($tuid && ($translator = User::load($tuid))) { $form['job_status'] = array('#type' => 'item', '#title' => t('Job status'), '#markup' => t('Translation job is assigned to %name.', array('%name' => $translator->getUsername()))); } else { $form['job_status'] = array('#type' => 'item', '#title' => t('Job status'), '#markup' => t('Translation job is not assigned to any user.')); } if ($job->getSetting('job_comment')) { $form['job_comment'] = array('#type' => 'item', '#title' => t('Job comment'), '#markup' => Xss::filter($job->getSetting('job_comment'))); } return $form; }
/** * Overrides Drupal\Core\Entity\EntityForm::form(). */ public function form(array $form, FormStateInterface $form_state) { $job = $this->entity; // Handle source language. $available['source_language'] = tmgmt_available_languages(); // Handle target language. $selected = $job->getSourceLangcode() != 'und' ?: array_keys(tmgmt_available_languages())[0]; $selected_option = [$selected => tmgmt_available_languages()[$selected]]; $available['target_language'] = array_diff(tmgmt_available_languages(), $selected_option); $this->entity->set('job_type', Job::TYPE_CONTINUOUS); $form = parent::form($form, $form_state); // Set the title of the page to the label and the current state of the job. $form['#title'] = t('@title', array('@title' => 'New Continuous Job')); $form['label']['widget'][0]['value']['#description'] = t('You need to provide a label for this job in order to identify it later on.'); $form['label']['widget'][0]['value']['#required'] = TRUE; $form['info']['source_language'] = array('#title' => t('Source language'), '#type' => 'select', '#options' => $available['source_language'], '#default_value' => $job->getSourceLangcode(), '#required' => TRUE, '#prefix' => '<div id="tmgmt-ui-source-language" class="tmgmt-ui-source-language tmgmt-ui-info-item">', '#suffix' => '</div>', '#ajax' => array('callback' => array($this, 'ajaxSourceLanguageSelect'), 'wrapper' => 'tmgmt-ui-target-language', 'event' => 'change')); $form['info']['target_language'] = array('#title' => t('Target language'), '#type' => 'select', '#options' => $available['target_language'], '#default_value' => $job->getTargetLangcode(), '#required' => TRUE, '#prefix' => '<div id="tmgmt-ui-target-language" class="tmgmt-ui-target-language tmgmt-ui-info-item">', '#suffix' => '</div>', '#ajax' => array('callback' => array($this, 'ajaxLanguageSelect'), 'wrapper' => 'tmgmt-ui-target-language'), '#validated' => TRUE); return $form; }
/** * Ajax callback to fetch the supported translator services and rebuild the * target / source language dropdowns. */ public function ajaxLanguageSelect(array $form, FormStateInterface $form_state) { $number_of_existing_items = count($this->entity->getConflictingItemIds()); $replace = $form_state->getUserInput()['_triggering_element_name'] == 'source_language' ? 'target_language' : 'source_language'; $response = new AjaxResponse(); $response->addCommand(new ReplaceCommand('#tmgmt-ui-translator-wrapper', $form['translator_wrapper'])); $response->addCommand(new ReplaceCommand('#tmgmt-ui-' . str_replace('_', '-', $replace), $form['info'][$replace])); if ($number_of_existing_items) { $response->addCommand(new InvokeCommand('.existing-items', 'removeClass', array('hidden'))); $response->addCommand(new ReplaceCommand('.existing-items > div', \Drupal::translation()->formatPlural($number_of_existing_items, '1 item conflict with pending item and will be dropped on submission.', '@count items conflict with pending items and will be dropped on submission.'))); } else { $response->addCommand(new InvokeCommand('.existing-items', 'addClass', array('hidden'))); } return $response; }
/** * {@inheritdoc} */ public function requestTranslation(JobInterface $job) { $tuid = $job->getSetting('translator'); // Create local task for this job. $local_task = tmgmt_local_task_create(array('uid' => $job->getOwnerId(), 'tuid' => $tuid, 'tjid' => $job->id(), 'title' => $job->label())); // If we have translator then switch to pending state. if ($tuid) { $local_task->status = LocalTaskInterface::STATUS_PENDING; } $local_task->save(); // Create task items. foreach ($job->getItems() as $item) { $local_task->addTaskItem($item); } // The translation job has been successfully submitted. $job->submitted(); }
/** * {@inheritdoc} */ function checkTranslatable(TranslatorInterface $translator, JobInterface $job) { if ($job->getSetting('action') == 'not_translatable') { return TranslatableResult::no(t('@translator can not translate from @source to @target.', array('@translator' => $job->getTranslator()->label(), '@source' => $job->getSourceLanguage()->getName(), '@target' => $job->getTargetLanguage()->getName()))); } return parent::checkTranslatable($translator, $job); }
/** * Provides a simple wrapper for the checkout info fieldset. * * @param \Drupal\tmgmt\JobInterface $job * Translation job object. * @param $form * Partial form structure to be wrapped in the fieldset. * * @return * The provided form structure wrapped in a collapsed fieldset. */ public function checkoutInfoWrapper(JobInterface $job, $form) { $label = $job->getTranslator()->label(); $form += array('#title' => t('@translator translation job information', array('@translator' => $label)), '#type' => 'details', '#open' => FALSE); return $form; }
/** * {@inheritdoc} */ public function requestTranslation(JobInterface $job) { // Pull the source data array through the job and flatten it. $data = \Drupal::service('tmgmt.data')->filterTranslatable($job->getData()); $translation = array(); foreach ($data as $key => $value) { // Query the translator API. try { $result = $this->doRequest($job->getTranslator(), 'Translate', array('from' => $job->getRemoteSourceLanguage(), 'to' => $job->getRemoteTargetLanguage(), 'contentType' => 'text/plain', 'text' => $value['#text']), array('Content-Type' => 'text/plain')); // Lets use DOMDocument for now because this service enables us to // send an array of translation sources, and we will probably use // this soon. $dom = new \DOMDocument(); $dom->loadXML($result->getBody()->getContents()); $items = $dom->getElementsByTagName('string'); $translation[$key]['#text'] = $items->item(0)->nodeValue; // The translation job has been successfully submitted. $job->submitted('The translation job has been submitted.'); // Save the translated data through the job. $job->addTranslatedData(\Drupal::service('tmgmt.data')->unflatten($translation)); } catch (RequestException $e) { $job->rejected('Rejected by Microsoft Translator: !error', array('!error' => $e->getResponse()->getBody()->getContents()), 'error'); } } }
/** * Implements TMGMTTranslatorPluginControllerInterface::requestTranslation(). */ public function requestTranslation(JobInterface $job) { // Pull the source data array through the job and flatten it. $data = \Drupal::service('tmgmt.data')->filterTranslatable($job->getData()); $translation = array(); $q = array(); $keys_sequence = array(); $i = 0; // Build Google q param and preserve initial array keys. foreach ($data as $key => $value) { $q[] = $value['#text']; $keys_sequence[] = $key; } try { // Split $q into chunks of self::qChunkSize. foreach (array_chunk($q, $this->qChunkSize) as $_q) { // Get translation from Google. $result = $this->googleRequestTranslation($job, $_q); // Collect translated texts with use of initial keys. foreach ($result['data']['translations'] as $translated) { $translation[$keys_sequence[$i]]['#text'] = $translated['translatedText']; $i++; } } // The translation job has been successfully submitted. $job->submitted('The translation job has been submitted.'); // Save the translated data through the job. // NOTE that this line of code is reached only in case all translation // requests succeeded. $job->addTranslatedData(\Drupal::service('tmgmt.data')->unflatten($translation)); } catch (TMGMTException $e) { $job->rejected('Translation has been rejected with following error: !error', array('!error' => $e->getMessage()), 'error'); } }
/** * {@inheritdoc} */ public function hasCheckoutSettings(JobInterface $job) { return $job->getTranslator()->getSetting('allow_override'); }
/** * Asserts import integrity for a job. * * @param \Drupal\tmgmt\JobInterface $job * The job to check. * @param bool $expected * (optional) If an integrity failed message is expected or not, defaults * to FALSE. */ protected function assertIntegrityCheck(JobInterface $job, $expected = TRUE) { $integrity_check_failed = FALSE; /** @var \Drupal\tmgmt\MessageInterface $message */ foreach ($job->getMessages() as $message) { if ($message->getMessage() == new TranslatableMarkup('Failed to validate semantic integrity of %key element. Please check also the HTML code of the element in the review process.', array('%key' => 'dummy][deep_nesting'))) { $integrity_check_failed = TRUE; break; } } // Check if the message was found or not, based on the expected argument. if ($expected) { $this->assertTrue($integrity_check_failed, 'The validation of semantic integrity must fail.'); } else { $this->assertFalse($integrity_check_failed, 'The validation of semantic integrity must not fail.'); } }
/** * Processes trans-unit/target to rebuild back the HTML. * * @param string $translation * Job data array. * @param \Drupal\tmgmt\JobInterface $job * Translation job. * * @return string */ protected function processForImport($translation, JobInterface $job) { // In case we do not want to do xliff processing return the translation as // is. if (!$job->getSetting('xliff_processing')) { return $translation; } $reader = new \XMLReader(); $reader->XML('<translation>' . $translation . '</translation>'); $text = ''; while ($reader->read()) { // If the current element is text append it to the result text. if ($reader->name == '#text' || $reader->name == '#cdata-section') { $text .= $reader->value; } elseif ($reader->name == 'x') { if ($reader->getAttribute('ctype') == 'lb') { $text .= '<br />'; } } elseif ($reader->name == 'ph') { if ($reader->getAttribute('ctype') == 'image') { $text .= '<img'; while ($reader->moveToNextAttribute()) { // @todo - we have to use x-html: prefixes for attributes. if ($reader->name != 'ctype' && $reader->name != 'id') { $text .= " {$reader->name}=\"{$reader->value}\""; } } $text .= ' />'; } } } return $text; }
/** * {@inheritdoc} */ public function abortTranslation(JobInterface $job) { // Assume that we can abort a translation job at any time. $job->aborted(); return TRUE; }