diff --git a/src/Entity/Controller/JobItemAccessControlHandler.php b/src/Entity/Controller/JobItemAccessControlHandler.php index ed88a92..f6a5d84 100644 --- a/src/Entity/Controller/JobItemAccessControlHandler.php +++ b/src/Entity/Controller/JobItemAccessControlHandler.php @@ -9,6 +9,7 @@ namespace Drupal\tmgmt\Entity\Controller; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Access\AccessResult; /** * Access control handler for the job item entity. @@ -21,7 +22,10 @@ class JobItemAccessControlHandler extends JobAccessControlHandler { * {@inheritdoc} */ protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) { - if ($entity->getJob()) { + if ($operation === 'delete') { + return AccessResult::allowedIf($entity->isInactive()); + } + else if ($entity->getJob()) { return $entity->getJob()->access($operation, $account, TRUE); } } diff --git a/src/Entity/JobItem.php b/src/Entity/JobItem.php index 4317d4a..1e8d392 100644 --- a/src/Entity/JobItem.php +++ b/src/Entity/JobItem.php @@ -827,7 +827,14 @@ class JobItem extends ContentEntityBase implements JobItemInterface { if (!$this->isActive() || !$this->getTranslatorPlugin()) { throw new TMGMTException('Cannot abort job item.'); } - return $this->setState(JobItemInterface::STATE_ABORTED); + $this->setState(JobItemInterface::STATE_ABORTED); + // Check if this was the last unfinished job item in this job. + $job = $this->getJob(); + if ($job && !$job->isContinuous() && tmgmt_job_check_finished($this->getJobId())) { + // Mark the job as finished in case it is a normal job. + $job->finished(); + } + return TRUE; } /** diff --git a/src/Entity/ListBuilder/JobItemListBuilder.php b/src/Entity/ListBuilder/JobItemListBuilder.php index ddbf3b3..e7b144a 100644 --- a/src/Entity/ListBuilder/JobItemListBuilder.php +++ b/src/Entity/ListBuilder/JobItemListBuilder.php @@ -33,17 +33,16 @@ class JobItemListBuilder extends EntityListBuilder { 'title' => t('View'), ); } - // Do not display delete on active job items, display abort. - if ($entity->getJob()->isActive() && $entity->isActive()) { - unset($operations['delete']); + // Display abort button on active or needs review job items. + if ($entity->isActive() || $entity->isNeedsReview()) { $operations['abort'] = array( 'url' => $entity->urlInfo('abort-form')->setOption('query', array('destination' => Url::fromRoute('')->getInternalPath())), 'title' => t('Abort'), 'weight' => 10, ); } - // Do not display delete on aborted job items also. - if ($entity->isAborted()) { + // Display delete only on inactive job items. + if (!$entity->access('delete')) { unset($operations['delete']); } return $operations; diff --git a/src/Form/JobItemAbortForm.php b/src/Form/JobItemAbortForm.php index 6217389..cee5e5a 100644 --- a/src/Form/JobItemAbortForm.php +++ b/src/Form/JobItemAbortForm.php @@ -26,7 +26,7 @@ class JobItemAbortForm extends ContentEntityConfirmFormBase { * {@inheritdoc} */ public function getDescription() { - return $this->t('This is only an internal decision and the translator does not know about it. After the action the job item will be aborted.'); + return $this->t('Aborted job items can no longer be accepted. The provider will not be notified.'); } /** diff --git a/src/JobItemInterface.php b/src/JobItemInterface.php index 4cf380e..ca7e179 100644 --- a/src/JobItemInterface.php +++ b/src/JobItemInterface.php @@ -166,8 +166,8 @@ interface JobItemInterface extends ContentEntityInterface { * Already accepted job items can not be aborted. Always use this method if * you want to abort a translation job item. * - * @return int - * The updated state of the job item if it could be set. + * @return bool + * TRUE if job item is successfully aborted. * * @throws \Drupal\tmgmt\TMGMTException * If fails to abort the job item. diff --git a/src/Tests/TMGMTUiTest.php b/src/Tests/TMGMTUiTest.php index 01aff91..1ae32bb 100644 --- a/src/Tests/TMGMTUiTest.php +++ b/src/Tests/TMGMTUiTest.php @@ -755,7 +755,6 @@ class TMGMTUiTest extends EntityTestBase { /** * Test the deletion and abortion of job item. * - * @todo This will in future check that delete is not allowed. * @todo There will be some overlap with Aborting items & testAbortJob. */ function testJobItemDelete() { @@ -798,7 +797,7 @@ class TMGMTUiTest extends EntityTestBase { // Reload job and check its state and state of its item. \Drupal::entityManager()->getStorage('tmgmt_job')->resetCache(); $job = Job::load($job->id()); - $this->assertTrue($job->isActive()); + $this->assertTrue($job->isFinished()); $items = $job->getItems(); $item = reset($items); $this->assertTrue($item->isAborted()); diff --git a/tmgmt.module b/tmgmt.module index ab93921..e61b634 100644 --- a/tmgmt.module +++ b/tmgmt.module @@ -256,7 +256,7 @@ function tmgmt_job_match_item($source_language, $target_language, $account = NUL function tmgmt_job_check_finished($tjid) { return !\Drupal::entityQuery('tmgmt_job_item') ->condition('tjid', $tjid) - ->condition('state', JobItem::STATE_ACCEPTED, '<>') + ->condition('state', [JobItem::STATE_ACCEPTED, JobItem::STATE_ABORTED], 'NOT IN') ->range(0, 1) ->count() ->execute();