Error message

Warning: count(): Parameter must be an array or an object that implements Countable in _api_make_match_member_link() (line 1230 of /home/projects/api/www/sites/all/modules/api/api.formatting.inc).

class Job

Entity class for the tmgmt_job entity.

Plugin annotation


@ContentEntityType(
  id = "tmgmt_job",
  label = @Translation("Translation Job"),
  module = "tmgmt",
  handlers = {
    "access" = "Drupal\tmgmt\Entity\Controller\JobAccessControlHandler",
    "form" = {
      "edit" = "Drupal\tmgmt\Form\JobForm",
      "abort" = "Drupal\tmgmt\Form\JobAbortForm",
      "delete" = "Drupal\Core\Entity\ContentEntityDeleteForm",
      "resubmit" = "Drupal\tmgmt\Form\JobResubmitForm",
      "continuous_add" = "Drupal\tmgmt\Form\ContinuousJobForm",
    },
    "list_builder" = "Drupal\tmgmt\Entity\ListBuilder\JobListBuilder",
    "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
    "views_data" = "Drupal\tmgmt\Entity\ViewsData\JobViewsData",
  },
  base_table = "tmgmt_job",
  entity_keys = {
    "id" = "tjid",
    "label" = "label",
    "uuid" = "uuid"
  },
  links = {
    "canonical" = "/admin/tmgmt/jobs/{tmgmt_job}",
    "abort-form" = "/admin/tmgmt/jobs/{tmgmt_job}/abort",
    "delete-form" = "/admin/tmgmt/jobs/{tmgmt_job}/delete",
    "resubmit-form" = "/admin/tmgmt/jobs/{tmgmt_job}/resubmit",
    "continuous-add-form" = "/admin/tmgmt/continuous_jobs/continuous_add",
  }
)

Hierarchy

  • class \Drupal\tmgmt\Entity\Job extends \Drupal\Core\Entity\ContentEntityBase implements \Drupal\user\EntityOwnerInterface, JobInterface

Expanded class hierarchy of Job

Related topics

31 files declare their use of Job
ConfigSourceUiTest.php in sources/tmgmt_config/tests/src/Functional/ConfigSourceUiTest.php
ContentEntitySource.php in sources/content/src/Plugin/tmgmt/Source/ContentEntitySource.php
ContentEntitySourceUnitTest.php in sources/content/tests/src/Kernel/ContentEntitySourceUnitTest.php
ContentTmgmtEntitySourceUiTest.php in sources/content/tests/src/Functional/ContentTmgmtEntitySourceUiTest.php
ContinuousJobForm.php in src/Form/ContinuousJobForm.php

... See full list

2 string references to 'Job'

File

src/Entity/Job.php, line 57

Namespace

Drupal\tmgmt\Entity
View source
class Job extends ContentEntityBase implements EntityOwnerInterface, JobInterface {

  /**
   * {@inheritdoc}
   */
  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
    $fields['tjid'] = BaseFieldDefinition::create('integer')
      ->setLabel(t('Job ID'))
      ->setDescription(t('The Job ID.'))
      ->setReadOnly(TRUE)
      ->setSetting('unsigned', TRUE);
    $fields['uuid'] = BaseFieldDefinition::create('uuid')
      ->setLabel(t('UUID'))
      ->setDescription(t('The node UUID.'))
      ->setReadOnly(TRUE);
    $fields['source_language'] = BaseFieldDefinition::create('language')
      ->setLabel(t('Source language code'))
      ->setDescription(t('The source language.'));
    $fields['target_language'] = BaseFieldDefinition::create('language')
      ->setLabel(t('Target language code'))
      ->setDescription(t('The target language.'));
    $fields['label'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Label'))
      ->setDescription(t('The label of this job.'))
      ->setDefaultValue('')
      ->setSettings(array(
      'max_length' => 255,
    ))
      ->setDisplayOptions('form', array(
      'type' => 'string',
      'weight' => -5,
    ))
      ->setDisplayConfigurable('form', TRUE);
    $fields['uid'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Owner'))
      ->setDescription(t('The user that is the job owner.'))
      ->setSettings(array(
      'target_type' => 'user',
    ))
      ->setDefaultValue(0);
    $fields['translator'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Provider'))
      ->setDescription(t('The selected provider'))
      ->setSettings(array(
      'target_type' => 'tmgmt_translator',
    ));
    $fields['settings'] = BaseFieldDefinition::create('map')
      ->setLabel(t('Settings'))
      ->setDescription(t('Provider specific configuration and context information for this job.'))
      ->setDefaultValue(array());
    $fields['reference'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Reference'))
      ->setDescription(t('Remote reference of this job'))
      ->setDefaultValue('')
      ->setSettings(array(
      'max_length' => 255,
    ));
    $fields['state'] = BaseFieldDefinition::create('list_integer')
      ->setLabel(t('Job state'))
      ->setDescription(t('The job state.'))
      ->setSetting('allowed_values', Job::getStates())
      ->setDefaultValue(Job::STATE_UNPROCESSED);
    $fields['created'] = BaseFieldDefinition::create('created')
      ->setLabel(t('Created'))
      ->setDescription(t('The time that the job was created.'));
    $fields['changed'] = BaseFieldDefinition::create('changed')
      ->setLabel(t('Changed'))
      ->setDescription(t('The time that the job was last edited.'));
    $fields['job_type'] = BaseFieldDefinition::create('list_string')
      ->setLabel(t('Job type'))
      ->setDescription(t('Type of job entity, can be Normal or Continuous.'))
      ->setSetting('allowed_values', [
      static::TYPE_NORMAL,
      static::TYPE_CONTINUOUS,
    ])
      ->setDefaultValue(static::TYPE_NORMAL);
    $fields['continuous_settings'] = BaseFieldDefinition::create('map')
      ->setLabel(t('Continuous settings'))
      ->setDescription(t('Continuous sources configuration.'))
      ->setDefaultValue(array());
    return $fields;
  }

  /**
   * {@inheritdoc}
   */
  public static function preCreate(EntityStorageInterface $storage, array &$values) {
    parent::preCreate($storage, $values);

    // If either the source or target language is empty.
    if (empty($values['source_language']) || empty($values['target_language'])) {
      $languages = tmgmt_available_languages();
      if (empty($values['source_language'])) {
        $values['source_language'] = key($languages);
      }
      if (empty($values['target_language'])) {

        // Values might be an array, simplify it to a scalar langcode.
        $source_language = $values['source_language'];
        while (is_array($source_language)) {
          $source_language = reset($source_language);
        }

        // Make sure the source language is not available as target language,
        // use the next best value as the default.
        unset($languages[$source_language]);
        $values['target_language'] = key($languages);
      }
    }
  }

  /**
   * If TRUE, getData will just return those items that are not yet translated.
   *
   * @var bool
   */
  protected $filterTranslatedItems = FALSE;

  /**
   * {@inheritdoc}
   */
  public function getTargetLanguage() {
    return $this
      ->get('target_language')->language;
  }

  /**
   * {@inheritdoc}
   */
  public function getTargetLangcode() {
    return $this
      ->get('target_language')->value;
  }

  /**
   * {@inheritdoc}
   */
  public function getSourceLanguage() {
    return $this
      ->get('source_language')->language;
  }

  /**
   * {@inheritdoc}
   */
  public function getSourceLangcode() {
    return $this
      ->get('source_language')->value;
  }

  /**
   * {@inheritdoc}
   */
  public function getChangedTime() {
    return $this
      ->get('changed')->value;
  }

  /**
   * {@inheritdoc}
   */
  public function getCreatedTime() {
    return $this
      ->get('created')->value;
  }

  /**
   * {@inheritdoc}
   */
  public function getReference() {
    return $this
      ->get('reference')->value;
  }

  /**
   * {@inheritdoc}
   */
  public function getJobType() {
    return $this
      ->get('job_type')->value;
  }

  /**
   * {@inheritdoc}
   */
  public function getContinuousSettings() {
    return $this
      ->get('continuous_settings')[0] ? $this
      ->get('continuous_settings')[0]
      ->getValue() : array();
  }

  /**
   * {@inheritdoc}
   */
  public function cloneAsUnprocessed() {
    $clone = $this
      ->createDuplicate();
    $clone->uid->value = 0;
    $clone->reference->value = '';
    $clone->created->value = \Drupal::time()
      ->getRequestTime();
    $clone->state->value = Job::STATE_UNPROCESSED;
    return $clone;
  }

  /**
   * {@inheritdoc}
   */
  public static function postDelete(EntityStorageInterface $storage, array $entities) {
    parent::postDelete($storage, $entities);
    $entity_type_manager = \Drupal::entityTypeManager();

    // Since we are deleting one or multiple jobs here we also need to delete
    // the attached job items and messages.
    $tjiids = \Drupal::entityQuery('tmgmt_job_item')
      ->accessCheck(TRUE)
      ->condition('tjid', array_keys($entities), 'IN')
      ->execute();
    if (!empty($tjiids)) {
      $job_items = $entity_type_manager
        ->getStorage('tmgmt_job_item')
        ->loadMultiple($tjiids);
      $entity_type_manager
        ->getStorage('tmgmt_job_item')
        ->delete($job_items);
    }
    $mids = \Drupal::entityQuery('tmgmt_message')
      ->accessCheck(TRUE)
      ->condition('tjid', array_keys($entities), 'IN')
      ->execute();
    if (!empty($mids)) {
      $messages = $entity_type_manager
        ->getStorage('tmgmt_message')
        ->loadMultiple($mids);
      $entity_type_manager
        ->getStorage('tmgmt_message')
        ->delete($messages);
    }
    $trids = \Drupal::entityQuery('tmgmt_remote')
      ->accessCheck(TRUE)
      ->condition('tjid', array_keys($entities), 'IN')
      ->execute();
    if (!empty($trids)) {
      $remotes = $entity_type_manager
        ->getStorage('tmgmt_remote')
        ->loadMultiple($trids);
      $entity_type_manager
        ->getStorage('tmgmt_remote')
        ->delete($remotes);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function label($langcode = NULL) {

    // In some cases we might have a user-defined label.
    if (!empty($this
      ->get('label')->value)) {
      return $this
        ->get('label')->value;
    }
    $items = $this
      ->getItems();
    $count = count($items);
    if ($count > 0) {
      $source_label = reset($items)
        ->getSourceLabel();
      $t_args = array(
        '@title' => $source_label,
        '@more' => $count - 1,
      );
      $label = \Drupal::translation()
        ->formatPlural($count, '@title', '@title and @more more', $t_args);

      // If the label length exceeds maximum allowed then cut off exceeding
      // characters from the title and use it to recreate the label.
      if (strlen($label) > Job::LABEL_MAX_LENGTH) {
        $max_length = strlen($source_label) - (strlen($label) - Job::LABEL_MAX_LENGTH);
        $source_label = Unicode::truncate($source_label, $max_length, TRUE);
        $t_args['@title'] = $source_label;
        $label = \Drupal::translation()
          ->formatPlural($count, '@title', '@title and @more more', $t_args);
      }
    }
    else {
      $source = $this
        ->getSourceLanguage() ? $this
        ->getSourceLanguage()
        ->getName() : '?';
      $target = $this
        ->getTargetLanguage() ? $this
        ->getTargetLanguage()
        ->getName() : '?';
      $label = t('From @source to @target', array(
        '@source' => $source,
        '@target' => $target,
      ));
    }
    return $label;
  }

  /**
   * {@inheritdoc}
   */
  public function addItem($plugin, $item_type, $item_id) {
    $transaction = \Drupal::database()
      ->startTransaction();
    $is_new = FALSE;
    if ($this
      ->isNew()) {
      $this
        ->save();
      $is_new = TRUE;
    }
    $item = tmgmt_job_item_create($plugin, $item_type, $item_id, array(
      'tjid' => $this
        ->id(),
    ));
    $item
      ->save();
    if ($item
      ->getWordCount() == 0) {
      $transaction
        ->rollback();

      // In case we got word count 0 for the first job item, NULL tjid so that
      // if there is another addItem() call the rolled back job object will get
      // persisted.
      if ($is_new) {
        $this->tjid = NULL;
      }
      throw new TMGMTException('Job item @label (@type) has no translatable content.', array(
        '@label' => $item
          ->label(),
        '@type' => $item
          ->getSourceType(),
      ));
    }
    return $item;
  }

  /**
   * {@inheritdoc}
   */
  public function addExistingItem(JobItemInterface $item) {
    $item->tjid = $this
      ->id();
    $item
      ->save();
  }

  /**
   * {@inheritdoc}
   */
  public function addMessage($message, $variables = array(), $type = 'status') {

    // Save the job if it hasn't yet been saved.
    if (!$this
      ->isNew() || $this
      ->save()) {
      $message = tmgmt_message_create($message, $variables, array(
        'tjid' => $this
          ->id(),
        'type' => $type,
      ));
      if ($message
        ->save()) {
        return $message;
      }
    }
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function getItems($conditions = array()) {
    $items = [];
    $query = \Drupal::entityQuery('tmgmt_job_item')
      ->accessCheck(TRUE)
      ->condition('tjid', $this
      ->id());
    foreach ($conditions as $key => $condition) {
      if (is_array($condition)) {
        $operator = isset($condition['operator']) ? $condition['operator'] : '=';
        $query
          ->condition($key, $condition['value'], $operator);
      }
      else {
        $query
          ->condition($key, $condition);
      }
    }
    $query
      ->sort('tjiid', 'ASC');
    $results = $query
      ->execute();
    if (!empty($results)) {
      $items = \Drupal::entityTypeManager()
        ->getStorage('tmgmt_job_item')
        ->loadMultiple($results);
      if ($this->filterTranslatedItems) {
        $items = array_filter($items, function (JobItemInterface $item) {
          return $item
            ->getCountPending() > 0;
        });
      }
    }
    return $items;
  }

  /**
   * {@inheritdoc}
   */
  public function getMostRecentItem($plugin, $item_type, $item_id) {
    $query = \Drupal::entityQuery('tmgmt_job_item')
      ->accessCheck(TRUE)
      ->condition('tjid', $this
      ->id())
      ->condition('plugin', $plugin)
      ->condition('item_type', $item_type)
      ->condition('item_id', $item_id)
      ->sort('tjiid', 'DESC')
      ->range(0, 1);
    $result = $query
      ->execute();
    if (!empty($result)) {
      return JobItem::load(reset($result));
    }
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function getMessages($conditions = array()) {
    $query = \Drupal::entityQuery('tmgmt_message')
      ->accessCheck(TRUE)
      ->condition('tjid', $this
      ->id());
    foreach ($conditions as $key => $condition) {
      if (is_array($condition)) {
        $operator = isset($condition['operator']) ? $condition['operator'] : '=';
        $query
          ->condition($key, $condition['value'], $operator);
      }
      else {
        $query
          ->condition($key, $condition);
      }
    }
    $query
      ->sort('created', 'ASC');
    $query
      ->sort('mid', 'ASC');
    $results = $query
      ->execute();
    if (!empty($results)) {
      return Message::loadMultiple($results);
    }
    return array();
  }

  /**
   * {@inheritdoc}
   */
  public function getMessagesSince($time = NULL) {
    $time = isset($time) ? $time : \Drupal::time()
      ->getRequestTime();
    $conditions = array(
      'created' => array(
        'value' => $time,
        'operator' => '>=',
      ),
    );
    return $this
      ->getMessages($conditions);
  }

  /**
   * {@inheritdoc}
   */
  public function getRemoteSourceLanguage() {
    return $this
      ->getTranslator()
      ->mapToRemoteLanguage($this
      ->getSourceLangcode());
  }

  /**
   * {@inheritdoc}
   */
  public function getRemoteTargetLanguage() {
    return $this
      ->getTranslator()
      ->mapToRemoteLanguage($this
      ->getTargetLangcode());
  }

  /**
   * {@inheritdoc}
   */
  public function getSetting($name) {
    if (isset($this->settings->{$name})) {
      return $this->settings->{$name};
    }

    // The translator might provide default settings.
    if ($this
      ->hasTranslator()) {
      if (($setting = $this
        ->getTranslator()
        ->getSetting($name)) !== NULL) {
        return $setting;
      }
      $defaults = $this
        ->getTranslatorPlugin()
        ->defaultSettings();
      if (isset($defaults[$name])) {
        return $defaults[$name];
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getTranslatorId() {
    return $this
      ->get('translator')->target_id;
  }

  /**
   * {@inheritdoc}
   */
  public function getTranslatorLabel() {
    if ($this
      ->hasTranslator()) {
      return $this
        ->getTranslator()
        ->label();
    }
    if ($this
      ->getTranslatorId() == NULL) {
      return t('(Undefined)');
    }
    return t('(Missing)');
  }

  /**
   * {@inheritdoc}
   */
  public function getTranslator() {
    if ($this
      ->hasTranslator()) {
      return $this->translator->entity;
    }
    else {
      if (!$this->translator->entity) {
        throw new TMGMTException('The job has no provider assigned.');
      }
      else {
        if (!$this->translator->entity
          ->hasPlugin()) {
          throw new TMGMTException('The translator assigned to this job is missing the plugin.');
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function hasTranslator() {
    return $this->translator->entity && $this->translator->target_id && $this->translator->entity
      ->hasPlugin();
  }

  /**
   * {@inheritdoc}
   */
  public function getState() {
    return $this
      ->get('state')->value;
  }

  /**
   * {@inheritdoc}
   */
  public function setState($state, $message = NULL, $variables = array(), $type = 'debug') {

    // Return TRUE if the state could be set. Return FALSE otherwise.
    if (array_key_exists($state, Job::getStates())) {
      $this->state = $state;
      $this
        ->save();

      // If a message is attached to this state change add it now.
      if (!empty($message)) {
        $this
          ->addMessage($message, $variables, $type);
      }
    }
    return $this
      ->getState();
  }

  /**
   * {@inheritdoc}
   */
  public function isState($state) {
    return $this
      ->getState() == $state;
  }

  /**
   * Checks whether the user described by $account is the author of this job.
   *
   * @param AccountInterface $account
   *   (Optional) A user object. Defaults to the currently logged in user.
   *
   * @return bool
   *   TRUE if the passed account is the job owner.
   */
  public function isAuthor(AccountInterface $account = NULL) {
    $account = isset($account) ? $account : \Drupal::currentUser();
    return $this
      ->getOwnerId() == $account
      ->id();
  }

  /**
   * {@inheritdoc}
   */
  public function isUnprocessed() {
    return $this
      ->isState(Job::STATE_UNPROCESSED);
  }

  /**
   * {@inheritdoc}
   */
  public function isAborted() {
    return $this
      ->isState(static::STATE_ABORTED);
  }

  /**
   * {@inheritdoc}
   */
  public function isActive() {
    return $this
      ->isState(static::STATE_ACTIVE);
  }

  /**
   * {@inheritdoc}
   */
  public function isRejected() {
    return $this
      ->isState(static::STATE_REJECTED);
  }

  /**
   * {@inheritdoc}
   */
  public function isFinished() {
    return $this
      ->isState(static::STATE_FINISHED);
  }

  /**
   * {@inheritdoc}
   */
  public function isContinuousActive() {
    return $this
      ->isState(static::STATE_CONTINUOUS);
  }

  /**
   * {@inheritdoc}
   */
  public function isContinuousInactive() {
    return $this
      ->isState(static::STATE_CONTINUOUS_INACTIVE);
  }

  /**
   * {@inheritdoc}
   */
  public function canRequestTranslation() {
    if ($translator = $this
      ->getTranslator()) {
      return $translator
        ->checkTranslatable($this);
    }
    return TranslatableResult::no(t('Translation cant be requested.'));
  }

  /**
   * {@inheritdoc}
   */
  public function isAbortable() {

    // Only non-submitted translation jobs can be aborted.
    if ($this
      ->isContinuous()) {
      return FALSE;
    }
    else {
      return $this
        ->isActive();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function isSubmittable() {
    if ($this
      ->isContinuous()) {
      return FALSE;
    }
    else {
      return $this
        ->isUnprocessed() || $this
        ->isRejected();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function isDeletable() {
    return !$this
      ->isActive();
  }

  /**
   * {@inheritdoc}
   */
  public function isContinuous() {
    return $this
      ->getJobType() == static::TYPE_CONTINUOUS;
  }

  /**
   * {@inheritdoc}
   */
  public function submitted($message = NULL, $variables = array(), $type = 'status') {
    if (!isset($message)) {
      $message = 'The translation job has been submitted.';
    }
    $this
      ->setState(static::STATE_ACTIVE, $message, $variables, $type);
  }

  /**
   * {@inheritdoc}
   */
  public function finished($message = NULL, $variables = array(), $type = 'status') {
    if (!isset($message)) {
      $message = 'The translation job has been finished.';
    }
    return $this
      ->setState(static::STATE_FINISHED, $message, $variables, $type);
  }

  /**
   * {@inheritdoc}
   */
  public function aborted($message = NULL, $variables = array(), $type = 'status') {
    if (!isset($message)) {
      $message = 'The translation job has been aborted.';
    }

    /** @var \Drupal\tmgmt\JobItemInterface $item */
    foreach ($this
      ->getItems() as $item) {
      $item
        ->setState(JobItem::STATE_ABORTED);
    }
    return $this
      ->setState(static::STATE_ABORTED, $message, $variables, $type);
  }

  /**
   * {@inheritdoc}
   */
  public function rejected($message = NULL, $variables = array(), $type = 'error') {
    if (!isset($message)) {
      $message = 'The translation job has been rejected by the translation provider.';
    }
    return $this
      ->setState(static::STATE_REJECTED, $message, $variables, $type);
  }

  /**
   * {@inheritdoc}
   */
  public function requestTranslation() {
    if (!$this
      ->canRequestTranslation()
      ->getSuccess()) {
      return FALSE;
    }
    if (!$this
      ->isContinuous()) {
      $this
        ->setOwnerId(\Drupal::currentUser()
        ->id());
    }

    // Call the hook before requesting the translation.
    \Drupal::moduleHandler()
      ->invokeAll('tmgmt_job_before_request_translation', [
      $this
        ->getItems(),
    ]);

    // We do not want to translate the items that are already translated.
    $this->filterTranslatedItems = TRUE;

    // We don't know if the translator plugin already processed our
    // translation request after this point. That means that the plugin has to
    // set the 'submitted', 'needs review', etc. states on its own.
    if (!empty($this
      ->getItems())) {
      $this
        ->getTranslatorPlugin()
        ->requestTranslation($this);
    }
    else {
      $this
        ->submitted();
    }

    // Reset it again so getData returns again all the values.
    $this->filterTranslatedItems = FALSE;

    // Call the hook after requesting the translation.
    \Drupal::moduleHandler()
      ->invokeAll('tmgmt_job_after_request_translation', [
      $this
        ->getItems(),
    ]);
  }

  /**
   * {@inheritdoc}
   */
  public function preSave(EntityStorageInterface $storage) {
    parent::preSave($storage);
    if ($this
      ->isContinuous() && !$this
      ->isContinuousInactive() && !$this
      ->isAborted()) {
      $this->state = Job::STATE_CONTINUOUS;
    }

    // Activate job item if the previous job state was not active.
    if ($this
      ->isActive() && (!isset($this->original) || !$this->original
      ->isActive())) {
      foreach ($this
        ->getItems() as $item) {

        // The job was submitted, activate any inactive job item.
        if ($item
          ->isInactive()) {
          $item
            ->setState(JobItemInterface::STATE_ACTIVE);
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function abortTranslation() {
    if (!$this
      ->isAbortable() || !($plugin = $this
      ->getTranslatorPlugin())) {
      return FALSE;
    }

    // We don't know if the translator plugin was able to abort the translation
    // job after this point. That means that the plugin has to set the
    // 'aborted' state on its own.
    return $plugin
      ->abortTranslation($this);
  }

  /**
   * {@inheritdoc}
   */
  public function getTranslatorPlugin() {
    return $this
      ->getTranslator()
      ->getPlugin();
  }

  /**
   * {@inheritdoc}
   */
  public function getData($key = array(), $index = NULL) {
    $data = array();
    if (!empty($key)) {
      $tjiid = array_shift($key);
      $item = JobItem::load($tjiid);
      if ($item) {
        $data[$tjiid] = $item
          ->getData($key, $index);

        // If not set, use the job item label as the data label.
        if (!isset($data[$tjiid]['#label'])) {
          $data[$tjiid]['#label'] = $item
            ->getSourceLabel();
        }
      }
    }
    else {
      foreach ($this
        ->getItems() as $tjiid => $item) {
        $data[$tjiid] = $item
          ->getData();

        // If not set, use the job item label as the data label.
        if (!isset($data[$tjiid]['#label'])) {
          $data[$tjiid]['#label'] = $item
            ->getSourceLabel();
        }
      }
    }
    return $data;
  }

  /**
   * {@inheritdoc}
   */
  public function getCountPending() {
    return tmgmt_job_statistic($this, 'count_pending');
  }

  /**
   * {@inheritdoc}
   */
  public function getCountTranslated() {
    return tmgmt_job_statistic($this, 'count_translated');
  }

  /**
   * {@inheritdoc}
   */
  public function getCountAccepted() {
    return tmgmt_job_statistic($this, 'count_accepted');
  }

  /**
   * {@inheritdoc}
   */
  public function getCountReviewed() {
    return tmgmt_job_statistic($this, 'count_reviewed');
  }

  /**
   * {@inheritdoc}
   */
  public function getWordCount() {
    return tmgmt_job_statistic($this, 'word_count');
  }

  /**
   * {@inheritdoc}
   */
  public function getTagsCount() {
    return tmgmt_job_statistic($this, 'tags_count');
  }

  /**
   * {@inheritdoc}
   */
  public function getFileCount() {
    return tmgmt_job_statistic($this, 'file_count');
  }

  /**
   * {@inheritdoc}
   */
  public function addTranslatedData(array $data, $key = NULL, $status = NULL) {
    $key = \Drupal::service('tmgmt.data')
      ->ensureArrayKey($key);
    $items = $this
      ->getItems();

    // If there is a key, get the specific item and forward the call.
    if (!empty($key)) {
      $item_id = array_shift($key);
      if (isset($items[$item_id])) {
        $items[$item_id]
          ->addTranslatedData($data, $key, $status);
      }
    }
    else {
      foreach ($data as $key => $value) {
        if (isset($items[$key])) {
          $items[$key]
            ->addTranslatedData($value, [], $status);
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function acceptTranslation() {
    foreach ($this
      ->getItems() as $item) {
      $item
        ->acceptTranslation();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getRemoteMappings() {
    $trids = \Drupal::entityQuery('tmgmt_remote')
      ->accessCheck(TRUE)
      ->condition('tjid', $this
      ->id())
      ->execute();
    if (!empty($trids)) {
      return RemoteMapping::loadMultiple($trids);
    }
    return array();
  }

  /**
   * {@inheritdoc}
   */
  public function getSuggestions(array $conditions = array()) {
    $suggestions = \Drupal::moduleHandler()
      ->invokeAll('tmgmt_source_suggestions', array(
      $this
        ->getItems($conditions),
      $this,
    ));

    // EachJob needs a job id to be able to count the words, because the
    // source-language is stored in the job and not the item.
    foreach ($suggestions as &$suggestion) {
      $jobItem = $suggestion['job_item'];
      $jobItem->tjid = $this
        ->id();
      $jobItem
        ->recalculateStatistics();
    }
    return $suggestions;
  }

  /**
   * {@inheritdoc}
   */
  public function cleanSuggestionsList(array &$suggestions) {
    foreach ($suggestions as $k => $suggestion) {
      if (is_array($suggestion) && isset($suggestion['job_item']) && $suggestion['job_item'] instanceof JobItem) {
        $jobItem = $suggestion['job_item'];

        // Items with no words to translate should not be presented.
        if ($jobItem
          ->getWordCount() <= 0) {
          unset($suggestions[$k]);
          continue;
        }

        // Check if there already exists a translation job for this item in the
        // current language.
        $items = tmgmt_job_item_load_all_latest($jobItem
          ->getPlugin(), $jobItem
          ->getItemType(), $jobItem
          ->getItemId(), $this
          ->getSourceLangcode());
        if (isset($items[$this
          ->getTargetLangcode()])) {
          unset($suggestions[$k]);
          continue;
        }

        // If the item is part of the current job, no matter which language,
        // remove it.
        foreach ($items as $item) {
          if ($item
            ->getJobId() == $this
            ->id()) {
            unset($suggestions[$k]);
            continue;
          }
        }
      }
      else {
        unset($suggestions[$k]);
        continue;
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function isTranslatable() {

    // Translation jobs themself can not be translated.
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function language() {
    return new Language(array(
      'id' => Language::LANGCODE_NOT_SPECIFIED,
    ));
  }

  /**
   * {@inheritdoc}
   */
  public function getOwner() {
    return $this
      ->get('uid')->entity;
  }

  /**
   * {@inheritdoc}
   */
  public function getOwnerId() {
    return $this
      ->get('uid')->target_id;
  }

  /**
   * {@inheritdoc}
   */
  public function setOwnerId($uid) {
    $this
      ->set('uid', $uid);
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setOwner(UserInterface $account) {
    $this
      ->set('uid', $account
      ->id());
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public static function getStates() {
    return array(
      static::STATE_UNPROCESSED => t('Unprocessed'),
      static::STATE_ACTIVE => t('Active'),
      static::STATE_REJECTED => t('Rejected'),
      static::STATE_ABORTED => t('Aborted'),
      static::STATE_FINISHED => t('Finished'),
      static::STATE_CONTINUOUS => t('Continuous'),
      static::STATE_CONTINUOUS_INACTIVE => t('Continuous Inactive'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getConflictingItemIds() {
    return array_keys($this
      ->getConflictingItems());
  }

  /**
   * {@inheritdoc}
   */
  public function getConflictingItems() {
    $conflicting_items = [];
    foreach ($this
      ->getItems() as $item) {

      // Get existing job items that are have the same languages, same source,
      // are active or in review and are not the job item that we are checking.
      $existing_items = \Drupal::entityQuery('tmgmt_job_item')
        ->accessCheck(TRUE)
        ->condition('state', [
        JobItemInterface::STATE_ACTIVE,
        JobItemInterface::STATE_REVIEW,
      ], 'IN')
        ->condition('plugin', $item
        ->getPlugin())
        ->condition('item_type', $item
        ->getItemType())
        ->condition('item_id', $item
        ->getItemId())
        ->condition('tjiid', $item
        ->id(), '<>')
        ->condition('tjid.entity.source_language', $this
        ->getSourceLangcode())
        ->condition('tjid.entity.target_language', $this
        ->getTargetLangcode())
        ->execute();

      // If there are any, this is a conflicting job item, so get the existing
      // items that are causing the conflict.
      if ($existing_items) {
        $conflicting_items[$item
          ->id()] = $existing_items;
      }
    }
    return $conflicting_items;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
Job::$filterTranslatedItems protected property If TRUE, getData will just return those items that are not yet translated.
Job::aborted public function Sets the state of the job to 'aborted'. Overrides JobInterface::aborted
Job::abortTranslation public function Attempts to abort the translation job. Overrides JobInterface::abortTranslation
Job::acceptTranslation public function Propagates the returned job item translations to the sources. Overrides JobInterface::acceptTranslation
Job::addExistingItem public function Add a givenJobItem to this job. Overrides JobInterface::addExistingItem
Job::addItem public function Adds an item to the translation job. Overrides JobInterface::addItem
Job::addMessage public function Add a log message for this job. Overrides JobInterface::addMessage
Job::addTranslatedData public function Store translated data back into the items. Overrides JobInterface::addTranslatedData
Job::baseFieldDefinitions public static function
Job::canRequestTranslation public function Checks whether a job is translatable. Overrides JobInterface::canRequestTranslation
Job::cleanSuggestionsList public function Removes all suggestions from the given list which should not be processed. Overrides JobInterface::cleanSuggestionsList
Job::cloneAsUnprocessed public function Clones job as unprocessed. Overrides JobInterface::cloneAsUnprocessed
Job::finished public function Set the state of the job to 'finished'. Overrides JobInterface::finished
Job::getChangedTime public function Returns the created time. Overrides JobInterface::getChangedTime
Job::getConflictingItemIds public function Returns conflicting job item IDs. Overrides JobInterface::getConflictingItemIds
Job::getConflictingItems public function Returns conflicting job item IDs along with the jobs causing the conflicts. Overrides JobInterface::getConflictingItems
Job::getContinuousSettings public function Returns continuous settings. Overrides JobInterface::getContinuousSettings
Job::getCountAccepted public function Sums up all accepted counts of this jobs job items. Overrides JobInterface::getCountAccepted
Job::getCountPending public function Sums up all pending counts of this jobs job items. Overrides JobInterface::getCountPending
Job::getCountReviewed public function Sums up all reviewed counts of this jobs job items. Overrides JobInterface::getCountReviewed
Job::getCountTranslated public function Sums up all translated counts of this jobs job items. Overrides JobInterface::getCountTranslated
Job::getCreatedTime public function Returns the created time. Overrides JobInterface::getCreatedTime
Job::getData public function Returns the source data of all job items. Overrides JobInterface::getData
Job::getFileCount public function Sums up all file counts of this jobs job items. Overrides JobInterface::getFileCount
Job::getItems public function Returns all job items attached to this job. Overrides JobInterface::getItems
Job::getJobType public function Returns the job type. Overrides JobInterface::getJobType
Job::getMessages public function Returns all job messages attached to this job. Overrides JobInterface::getMessages
Job::getMessagesSince public function Returns all job messages attached to this job. Overrides JobInterface::getMessagesSince
Job::getMostRecentItem public function Returns most recent job item attached to this job. Overrides JobInterface::getMostRecentItem
Job::getOwner public function
Job::getOwnerId public function
Job::getReference public function Returns the reference. Overrides JobInterface::getReference
Job::getRemoteMappings public function Gets remote mappings for current job. Overrides JobInterface::getRemoteMappings
Job::getRemoteSourceLanguage public function Returns remote source language code. Overrides JobInterface::getRemoteSourceLanguage
Job::getRemoteTargetLanguage public function Returns remote target language code. Overrides JobInterface::getRemoteTargetLanguage
Job::getSetting public function Retrieves a setting value from the job settings. Overrides JobInterface::getSetting
Job::getSourceLangcode public function Returns the source language code. Overrides JobInterface::getSourceLangcode
Job::getSourceLanguage public function Returns the source language. Overrides JobInterface::getSourceLanguage
Job::getState public function Returns the state of the job. Can be one of the job state constants. Overrides JobInterface::getState
Job::getStates public static function Returns a labeled list of all available states. Overrides JobInterface::getStates
Job::getSuggestions public function Invoke the hook 'hook_tmgmt_source_suggestions' to get all suggestions. Overrides JobInterface::getSuggestions
Job::getTagsCount public function Sums up all HTML tags counts of this jobs job items. Overrides JobInterface::getTagsCount
Job::getTargetLangcode public function Returns the target language code. Overrides JobInterface::getTargetLangcode
Job::getTargetLanguage public function Returns the target language. Overrides JobInterface::getTargetLanguage
Job::getTranslator public function Returns the translator for this job. Overrides JobInterface::getTranslator
Job::getTranslatorId public function Returns the translator ID for this job. Overrides JobInterface::getTranslatorId
Job::getTranslatorLabel public function Returns the label of the translator for this job. Overrides JobInterface::getTranslatorLabel
Job::getTranslatorPlugin public function Returns the translator plugin of the translator of this job. Overrides JobInterface::getTranslatorPlugin
Job::getWordCount public function Sums up all word counts of this jobs job items. Overrides JobInterface::getWordCount
Job::hasTranslator public function Checks if the translator and the plugin exist. Overrides JobInterface::hasTranslator
Job::isAbortable public function Checks whether a job is abortable. Overrides JobInterface::isAbortable
Job::isAborted public function Returns whether the state of this job is 'aborted'. Overrides JobInterface::isAborted
Job::isActive public function Returns whether the state of this job is 'active'. Overrides JobInterface::isActive
Job::isAuthor public function Checks whether the user described by $account is the author of this job. Overrides JobInterface::isAuthor
Job::isContinuous public function Checks whether a job type is continuous. Overrides JobInterface::isContinuous
Job::isContinuousActive public function Returns whether the state of this job is 'continuous'. Overrides JobInterface::isContinuousActive
Job::isContinuousInactive public function Returns whether the state of this jon is 'continuous_inactive'. Overrides JobInterface::isContinuousInactive
Job::isDeletable public function Checks whether a job is deletable. Overrides JobInterface::isDeletable
Job::isFinished public function Returns whether the state of this job is 'finished'. Overrides JobInterface::isFinished
Job::isRejected public function Returns whether the state of this job is 'rejected'. Overrides JobInterface::isRejected
Job::isState public function Checks whether the passed value matches the current state. Overrides JobInterface::isState
Job::isSubmittable public function Checks whether a job is submittable. Overrides JobInterface::isSubmittable
Job::isTranslatable public function
Job::isUnprocessed public function Returns whether the state of this job is 'unprocessed'. Overrides JobInterface::isUnprocessed
Job::label public function
Job::language public function
Job::postDelete public static function
Job::preCreate public static function
Job::preSave public function
Job::rejected public function Sets the state of the job to 'rejected'. Overrides JobInterface::rejected
Job::requestTranslation public function Request the translation of a job from the translator. Overrides JobInterface::requestTranslation
Job::setOwner public function
Job::setOwnerId public function
Job::setState public function Updates the state of the job. Overrides JobInterface::setState
Job::submitted public function Set the state of the job to 'submitted'. Overrides JobInterface::submitted
JobInterface::LABEL_MAX_LENGTH constant Maximum length of a job or job item label.
JobInterface::STATE_ABORTED constant The translation job has been aborted.
JobInterface::STATE_ACTIVE constant A translation job that has been submitted to the translator.
JobInterface::STATE_CONTINUOUS constant A continuous translation job.
JobInterface::STATE_CONTINUOUS_INACTIVE constant A continuous translation job has been inactivated.
JobInterface::STATE_FINISHED constant The translation job has been finished.
JobInterface::STATE_REJECTED constant A translation job that has been rejected by the translator.
JobInterface::STATE_UNPROCESSED constant A new translation job.
JobInterface::TYPE_CONTINUOUS constant Translation job of type Continuous.
JobInterface::TYPE_NORMAL constant Translation job of type Normal.