View source
<?php
namespace Drupal\tmgmt_local\Form;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Render\Element;
use Drupal\tmgmt\SourcePreviewInterface;
use Drupal\filter\Entity\FilterFormat;
use Drupal\tmgmt_local\Entity\LocalTaskItem;
use Drupal\tmgmt_local\LocalTaskInterface;
use Drupal\views\Views;
class LocalTaskItemForm extends ContentEntityForm {
protected $entity;
public function form(array $form, FormStateInterface $form_state) {
$form = parent::form($form, $form_state);
$task_item = $this->entity;
$form['#title'] = $task_item
->label();
$job_item = $task_item
->getJobItem();
$job = $job_item
->getJob();
$form['info'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'tmgmt-local-task-info',
'clearfix',
),
),
'#weight' => 0,
);
$url = $job_item
->getSourceUrl();
$form['info']['source'] = array(
'#type' => 'item',
'#title' => t('Source'),
'#markup' => $url ? Link::fromTextAndUrl($job_item
->getSourceLabel(), $url)
->toString() : $job_item
->getSourceLabel(),
'#prefix' => '<div class="tmgmt-ui-source tmgmt-ui-info-item">',
'#suffix' => '</div>',
);
$form['info']['sourcetype'] = array(
'#type' => 'item',
'#title' => t('Source type'),
'#markup' => $job_item
->getSourceType(),
'#prefix' => '<div class="tmgmt-ui-source-type tmgmt-ui-info-item">',
'#suffix' => '</div>',
);
$form['info']['source_language'] = array(
'#type' => 'item',
'#title' => t('Source language'),
'#markup' => $job_item
->getJob()
->getSourceLanguage()
->getName(),
'#prefix' => '<div class="tmgmt-ui-source-language tmgmt-ui-info-item">',
'#suffix' => '</div>',
);
$form['info']['target_language'] = array(
'#type' => 'item',
'#title' => t('Target language'),
'#markup' => $job_item
->getJob()
->getTargetLanguage()
->getName(),
'#prefix' => '<div class="tmgmt-ui-target-language tmgmt-ui-info-item">',
'#suffix' => '</div>',
);
$form['info']['changed'] = array(
'#type' => 'item',
'#title' => t('Last change'),
'#value' => $task_item
->getChangedTime(),
'#markup' => \Drupal::service('date.formatter')
->format($task_item
->getChangedTime()),
'#prefix' => '<div class="tmgmt-ui-changed tmgmt-ui-info-item">',
'#suffix' => '</div>',
);
$statuses = LocalTaskItem::getStatuses();
$form['info']['status'] = array(
'#type' => 'item',
'#title' => t('Status'),
'#markup' => $statuses[$task_item
->getStatus()],
'#prefix' => '<div class="tmgmt-ui-task-item-status tmgmt-ui-info-item">',
'#suffix' => '</div>',
'#value' => $task_item
->getStatus(),
);
$task = $task_item
->getTask();
$url = $task
->toUrl();
$form['info']['task'] = array(
'#type' => 'item',
'#title' => t('Task'),
'#markup' => Link::fromTextAndUrl($task
->label(), $url)
->toString(),
'#prefix' => '<div class="tmgmt-ui-task tmgmt-ui-info-item">',
'#suffix' => '</div>',
);
if ($job
->getSetting('job_comment')) {
$form['job_comment'] = array(
'#type' => 'item',
'#title' => t('Job comment'),
'#markup' => Xss::filter($job
->getSetting('job_comment')),
);
}
$form['translation'] = array(
'#type' => 'container',
);
$data = $task_item
->getData();
$zebra = 'even';
foreach (Element::children($data) as $key) {
$flattened = \Drupal::service('tmgmt.data')
->flatten($data[$key], $key);
$form['translation'][$key] = $this
->formElement($flattened, $task_item, $zebra);
}
$form['footer'] = tmgmt_color_local_review_legend();
$form['#attached']['library'][] = 'tmgmt/admin';
return $form;
}
protected function actions(array $form, FormStateInterface $form_state) {
$task_item = $this->entity;
$actions['save_as_completed'] = array(
'#type' => 'submit',
'#button_type' => 'primary',
'#validate' => [
'::validateSaveAsComplete',
],
'#submit' => [
'::save',
'::saveAsComplete',
],
'#access' => $task_item
->isPending(),
'#value' => t('Save as completed'),
);
$actions['save'] = array(
'#type' => 'submit',
'#submit' => [
'::save',
],
'#access' => $task_item
->isPending(),
'#value' => t('Save'),
);
$job_item = $task_item
->getJobItem();
if ($job_item
->getSourcePlugin() instanceof SourcePreviewInterface && $job_item
->getSourcePlugin()
->getPreviewUrl($job_item)) {
$actions['preview'] = [
'#type' => 'submit',
'#submit' => [
'::save',
'::preview',
],
'#access' => $task_item
->isPending(),
'#value' => t('Preview'),
];
}
return $actions;
}
private function formElement(array $data, LocalTaskItem $item, &$zebra) {
static $flip = array(
'even' => 'odd',
'odd' => 'even',
);
$form = [];
$job = $item
->getJobItem()
->getJob();
$language_list = \Drupal::languageManager()
->getLanguages();
foreach (Element::children($data) as $key) {
if (isset($data[$key]['#text']) && \Drupal::service('tmgmt.data')
->filterData($data[$key])) {
$target_key = str_replace('][', '|', $key);
$zebra = $flip[$zebra];
$form[$target_key] = array(
'#tree' => TRUE,
'#theme' => 'tmgmt_local_translation_form_element',
'#ajaxid' => Html::getUniqueId('tmgmt-local-element-' . $key),
'#parent_label' => $data[$key]['#parent_label'],
'#zebra' => $zebra,
);
$form[$target_key]['status'] = array(
'#theme' => 'tmgmt_local_translation_form_element_status',
'#value' => $this->entity
->isCompleted() ? TMGMT_DATA_ITEM_STATE_COMPLETED : $data[$key]['#status'],
);
$rows = ceil(strlen($data[$key]['#text']) / 100);
if ($rows < 3) {
$rows = 3;
}
elseif ($rows > 15) {
$rows = 15;
}
$form[$target_key]['source'] = [
'#type' => 'textarea',
'#value' => $data[$key]['#text'],
'#title' => t('Source'),
'#disabled' => TRUE,
'#rows' => $rows,
];
$form[$target_key]['translation'] = [
'#type' => 'textarea',
'#default_value' => isset($data[$key]['#translation']['#text']) ? $data[$key]['#translation']['#text'] : NULL,
'#title' => t('Translation'),
'#disabled' => !$item
->isPending(),
'#rows' => $rows,
'#allow_focus' => TRUE,
];
if (!empty($data[$key]['#format']) && \Drupal::config('tmgmt.settings')
->get('respect_text_format') == '1') {
$format_id = $data[$key]['#format'];
$format = FilterFormat::load($format_id);
if ($format && $format
->access('use')) {
$form[$target_key]['source']['#allowed_formats'] = [
$format_id,
];
$form[$target_key]['translation']['#allowed_formats'] = [
$format_id,
];
$form[$target_key]['source']['#type'] = 'text_format';
$form[$target_key]['translation']['#type'] = 'text_format';
}
}
$form[$target_key]['actions'] = array(
'#type' => 'container',
'#access' => $item
->isPending(),
);
$status = $item
->getData(\Drupal::service('tmgmt.data')
->ensureArrayKey($key), '#status');
if ($status == TMGMT_DATA_ITEM_STATE_TRANSLATED) {
$form[$target_key]['actions']['reject-' . $target_key] = array(
'#type' => 'submit',
'#value' => '✗',
'#attributes' => array(
'title' => t('Reject'),
),
'#name' => 'reject-' . $target_key,
'#submit' => [
'::save',
'::submitStatus',
],
'#ajax' => array(
'callback' => '::ajaxReviewForm',
'wrapper' => $form[$target_key]['#ajaxid'],
),
'#tmgmt_local_action' => 'reject',
'#tmgmt_local_key' => str_replace('][', '|', $key),
);
}
else {
$form[$target_key]['actions']['finish-' . $target_key] = array(
'#type' => 'submit',
'#value' => '✓',
'#attributes' => array(
'title' => t('Finish'),
),
'#name' => 'finish-' . $target_key,
'#submit' => [
'::save',
'::submitStatus',
],
'#ajax' => array(
'callback' => '::ajaxReviewForm',
'wrapper' => $form[$target_key]['#ajaxid'],
),
'#tmgmt_local_action' => 'finish',
'#tmgmt_local_key' => str_replace('][', '|', $key),
);
}
}
}
return $form;
}
public function save(array $form, FormStateInterface $form_state) {
parent::save($form, $form_state);
$task_item = $this->entity;
$form_state
->cleanValues();
foreach ($form_state
->getValues() as $key => $value) {
if (is_array($value) && isset($value['translation'])) {
if (is_array($value['translation'])) {
$update['#translation']['#text'] = $value['translation']['value'];
}
else {
$update['#translation']['#text'] = $value['translation'];
}
$task_item
->updateData($key, $update);
}
}
$task_item
->save();
if ($form_state
->getTriggeringElement()['#value'] == $form['actions']['save']['#value']) {
$this
->messenger()
->addStatus(t('The translation for <a href=:task_item>@task_item_title</a> has been saved.', [
':task_item' => $task_item
->toUrl()
->toString(),
'@task_item_title' => $task_item
->label(),
]));
}
$task = $task_item
->getTask();
$uri = $task
->toUrl();
$form_state
->setRedirect($uri
->getRouteName(), $uri
->getRouteParameters());
}
public function saveAsComplete(array &$form, FormStateInterface $form_state) {
$task = $this->entity
->getTask();
$task_item = $this->entity;
$task_item
->completed();
$task_item
->save();
$all_done = TRUE;
foreach ($task
->getItems() as $item) {
if (!$item
->isCompleted() && !$item
->isClosed()) {
$all_done = FALSE;
break;
}
}
if ($all_done) {
$task
->setStatus(LocalTaskInterface::STATUS_COMPLETED);
$view = Views::getView('tmgmt_local_task_overview');
$view
->initDisplay();
$form_state
->setRedirect($view
->getUrl()
->getRouteName());
}
else {
$uri = $task
->toUrl();
$form_state
->setRedirect($uri
->getRouteName(), $uri
->getRouteParameters());
}
$job_item = $this->entity
->getJobItem();
$job_item
->addTranslatedData($this
->prepareData($task_item
->getData()), [], TMGMT_DATA_ITEM_STATE_TRANSLATED);
$this
->messenger()
->addStatus(t('The translation for <a href=:task_item>@task_item_title</a> has been saved as completed.', [
':task_item' => $task_item
->toUrl()
->toString(),
'@task_item_title' => $task_item
->label(),
]));
}
public function validateSaveAsComplete(array &$form, FormStateInterface $form_state) {
foreach ($form_state
->getValues() as $key => $value) {
if (is_array($value) && isset($value['translation'])) {
if (empty($value['translation'])) {
$form_state
->setErrorByName($key . '[translation]', t('Missing translation.'));
}
}
}
}
public function ajaxReviewForm(array $form, FormStateInterface $form_state) {
$key = array_slice($form_state
->getTriggeringElement()['#array_parents'], 0, 3);
$render_data = NestedArray::getValue($form, $key);
return $render_data;
}
public function submitStatus(array $form, FormStateInterface $form_state) {
$values = $form_state
->getValues();
$item = $this->entity;
$action = $form_state
->getTriggeringElement()['#tmgmt_local_action'];
$key = $form_state
->getTriggeringElement()['#tmgmt_local_key'];
if (isset($values[$key]) && is_array($values[$key]) && isset($values[$key]['translation'])) {
$update['#status'] = $action == 'finish' ? TMGMT_DATA_ITEM_STATE_TRANSLATED : TMGMT_DATA_ITEM_STATE_UNTRANSLATED;
$item
->updateData($key, $update);
$item
->save();
$form_state
->setRebuild();
}
}
protected function prepareData(array $data) {
if (isset($data['#text'])) {
if (isset($data['#translation']['#text'])) {
$result['#text'] = $data['#translation']['#text'];
}
else {
$result['#text'] = '';
}
return $result;
}
foreach (Element::children($data) as $key) {
$data[$key] = $this
->prepareData($data[$key]);
}
return $data;
}
public function preview(array $form, FormStateInterface $form_state) {
$task_item = $this->entity;
$job_item = $task_item
->getJobItem();
$job_item
->addTranslatedData($this
->prepareData($task_item
->getData()), [], TMGMT_DATA_ITEM_STATE_PRELIMINARY);
$url = $job_item
->getSourcePlugin()
->getPreviewUrl($job_item);
$form_state
->setRedirectUrl($url);
}
}