lionbridge_translation_provider-8.x-2.4/tmgmt_contentapi/src/Services/ImportJob.php

tmgmt_contentapi/src/Services/ImportJob.php
<?php

namespace Drupal\tmgmt_contentapi\Services;

use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\file\Entity\File;
use Drupal\File\FileRepositoryInterface;
use Drupal\tmgmt\Entity\Job;
use Drupal\tmgmt\Entity\JobItem;
use drupal\tmgmt\JobInterface;
use Drupal\tmgmt_contentapi\Plugin\tmgmt_contentapi\Format\Xliff;
use Drupal\tmgmt_contentapi\Services\CapiDataProcessor;
use Drupal\tmgmt_contentapi\Swagger\Client\Api\FileApi;
use Drupal\tmgmt_contentapi\Swagger\Client\Api\JobApi;
use Drupal\tmgmt_contentapi\Swagger\Client\Api\RequestApi;
use Drupal\tmgmt_contentapi\Swagger\Client\Api\TokenApi;
use Drupal\tmgmt_contentapi\Swagger\Client\Configuration;
use Drupal\tmgmt_contentapi\Swagger\Client\Model\ArrayOfRequestIds;
use Drupal\tmgmt_contentapi\Services\JobHelper;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\tmgmt_contentapi\Services\QueueOperations;

/**
 * Class ProcessJob.
 *
 * @category Class
 * @package Drupaltmgmt_ContentapiServices
 * @author Pankaj Raundal <pankaj.raundal@lionbridge.com>
 * @license MIT License
 * @link https://www.lionbridge.com
 */
class ImportJob {
  use StringTranslationTrait;

  /**
   * The capi token.
   *
   * @var string
   */
  protected $capiToken;

  /**
   * Public file path for received files.
   */
  const PUBLIC_RECEIVED_FILE_PATH = '://tmgmt_contentapi/LioxReceivedFiles/';

  /**
   * If provider allows to auto accept jobs.
   *
   * @var bool
   */
  protected $isAutoAccept;

  /**
   * Capi data processor.
   *
   * @var \Drupal\tmgmt_contentapi\Services\CapiDataProcessor
   */
  protected $capiDataProcessor;

  /**
   * Logger Factory.
   *
   * @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
   */
  protected $logger;

  /**
   * The queue operations.
   *
   * @var \Drupal\tmgmt_contentapi\Services\QueueOperations
   */
  protected $queueOperations;

  /**
   * State key for queue worker.
   */
  const QUEUE_WORKER_IMPORT_TRANSLATION_JOBS_TO_CAPI = 'queue_worker_import_translated_jobs_from_queue';

  /**
   * Queue name for import translation jobs to capi.
   */
  const QUEUE_NAME_IMPORT_JOBS = 'import_translated_jobs_from_queue';

  /**
   * Queue name for import translation jobs manually.
   */
  const QUEUE_NAME_IMPORT_JOBS_MANUALLY = 'import_jobs_manually_from_queue';

  /**
   * Consructor.
   *
   * @param \Drupal\tmgmt_contentapi\Services\CapiDataProcessor $capiDataProcessor
   *   Service for capi data processor.
   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
   *   Service for logger factory.
   * @param \Drupal\tmgmt_contentapi\Services\QueueOperations $queueOperations
   *   Service for queue operations.
   */
  public function __construct(
    CapiDataProcessor $capiDataProcessor,
    LoggerChannelFactoryInterface $logger_factory,
    QueueOperations $queueOperations,
  ) {
    $this->capiDataProcessor = $capiDataProcessor;
    $this->logger = $logger_factory;
    $this->queueOperations = $queueOperations;
  }

  /**
   * Create a new instance of the class.
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   The container instance.
   *
   * @return static
   *   The created instance of the class.
   */
  public static function create(ContainerInterface $container) {
    return new static(
          $container->get('tmgmt_contentapi.capi_data_processor'),
          $container->get('logger.factory'),
      );
  }

  /**
   * Function to keep directory ready to receive files.
   *
   * @param \\drupal\tmgmt\JobInterface $job
   *   Job object.
   */
  protected function prepareDirectory(JobInterface $job) {
    $config = new Configuration();
    $dir = $job->getSetting('scheme') . self::PUBLIC_RECEIVED_FILE_PATH;
    // Check if you able to create directory for above mentioned path.
    if (!\Drupal::service('file_system')->prepareDirectory($dir, FileSystemInterface::CREATE_DIRECTORY)) {
      $this->logger->get('TMGMT_CONTENTAPI')->error(
            $this->t('Directory could not be created:', [
              '%dir' => $dir,
            ])
        );
      return;
    }
    $stmrg = \Drupal::service('stream_wrapper_manager')->getViaUri($dir);
    $tempfolder = $stmrg->realpath();
    $config->setTempFolderPath($tempfolder);
    Configuration::setDefaultConfiguration($config);
    unset($config);
  }

  /**
   * Function initiate the import process.
   *
   * @param string $tjid
   *   Tmgmt job id.
   */
  public function initiateImport($tjid = '') {
    try {
      // Get all the ready request id to import.
      $import_ready_request = $this->capiDataProcessor->getAllReadyRequestIdToImport($tjid);
      // If no request id found then return.
      if (empty($import_ready_request)) {
        return;
      }
      $queue_items = $this->queueOperations->getQueueItems(self::QUEUE_NAME_IMPORT_JOBS, 'rid');
      $queue_items_zip = $this->queueOperations->getQueueItems(self::QUEUE_NAME_IMPORT_JOBS_MANUALLY, 'rid');
      // Verify if any queue items are present in both queues.
      $queue_items = array_merge($queue_items, $queue_items_zip);
      // Foreach request id create a job and item.
      foreach ($import_ready_request as $key => $data) {
        $job_info = [
          'rid' => $data->rid,
          'tjid' => $data->tjid,
          'job_id' => $data->jobid,
          'provider_id' => $data->providerid,
          'update_id' => $data->updateid,
          'statuscode' => $data->statuscode,
          'request_id' => $data->requestid,
          'status' => $data->status,
        ];
        // While processing we need to make sure if this item is coming via auto import.
        // Accordingly we need to process the item, skip or process.
        if ($tjid == '') {
          $job_info['via_auto_import'] = TRUE;
        }

        // If item is already in queue avoid re-adding same item to queue.
        if (!in_array($data->rid, $queue_items)) {
          // If item not exist in queue add it again.
          if (\Drupal::service('queue')->get(self::QUEUE_NAME_IMPORT_JOBS)->createItem($job_info)) {
            // If successfully added to queue then update the status of request id to IN_QUEUE.
            $this->capiDataProcessor->setRequestItemInQueueStatus($data->rid);
          }
        }
      }
      // Display message to user when request id added to queue.
      if ($tjid != '') {
        $messageToPass = $this->t('The job import process has started and is running in the background. You can check the progress and updated status on the Job Overview page.');
        \Drupal::messenger()->addMessage($messageToPass);
      }
    }
    catch (\Exception $exception) {
      $respbody = $exception->getMessage();
      if ($exception instanceof ApiException) {
        $respbody = $exception->getResponseBody();
      }
      $respbody = 'An error occured while fetching and importing files: ' . $respbody;
      if (strlen($respbody) > 200) {
        $respbody = substr($respbody, 0, 200);
      }
      \Drupal::messenger()->addMessage($respbody, 'error');
    }
  }

  /**
   * Function to process request in a batch.
   *
   * @param array $job_info
   *   Job related information.
   */
  public function processRequestId(array $job_info) {
    $fileApi = new fileApi();
    // Generate Job and item details.
    $job = job::load($job_info['tjid']);
    $job_id = $job_info['job_id'];
    if (!$job) {
      $this->logger->get('TMGMT_CONTENTAPI_JOB_NOT_FOUND')->error(
            'Job not found for job id: @jobid, import aborted.',
            [
              '@jobid' => $job_id . "_" . $job_info['tjid'],
            ]
        );
      return;
    }
    $translator = $job->getTranslator();
    // Check if item is coming via auto import. if yes then check if translator is set to auto import.
    // If not then return.
    if (isset($job_info['via_auto_import']) && $job_info['via_auto_import'] == TRUE) {
      $iscronset = $translator->getSetting('cron-settings')['status'];
      $process_method = $translator->getSetting('process_method');
      // If auto import is not set then return.
      // If process method is set to fail safe then return.
      if (!$iscronset || $process_method) {
        // Update tmgmt_capi_request_processor is processed status to TO_PROCESS.
        $this->capiDataProcessor->setRequestItemInQueueStatus($job_info['rid'], $this->capiDataProcessor::TO_PROCESS);
        return;
      }
    }
    // Is auto accept on.
    $this->isAutoAccept = $translator->isAutoAccept();
    // Validate and generate token if required.
    $this->capiToken = \DRUPAL::service('tmgmt_contentapi.capi_details')->getCapiToken($translator);
    // Step 1: Get the file from CAPI.
    $spfilearray = $fileApi->jobsJobIdRequestsRequestIdRetrievefileGetWithHttpInfo($this->capiToken, $job_id, $job_info['request_id']);
    $spfile = $spfilearray[0];
    $fcontent = $spfile->fread($spfile->getSize());
    $fpath = $spfile->getRealPath();
    $spfilearray[0] = NULL;
    $spfile = NULL;
    \Drupal::service('file_system')->delete($fpath);
    // Step 2: Get the file name.
    $filename = str_replace('"', '', explode("=", explode(";", $spfilearray[2]['Content-Disposition'][0])[1])[1]);
    // If spfilearray is empty return or filename is empty balnk or $fcontent is empty return.
    if (empty($spfilearray) || $filename == '' || $fcontent === FALSE || $fcontent === "") {
      $this->logger->get('TMGMT_CONTENTAPI_FILE_RETRIEVE_FAILED')->error(
            'Failed to get file for item: @jobinfo, import aborted.',
            [
              '%jobinfo' => json_encode($job_info),
            ]
        );
      return;
    }
    // Step 3: Import the job for review and accept.
    $import_status = $this->importJob($job, $fcontent, $filename, $job_info['update_id'], $job_info['rid']);
    if ($import_status == 'zip_extracted_items_queued') {
      // If zip file is extracted and items are queued then return.
      $this->logger->get('TMGMT_CONTENTAPI_ZIP_EXTRACTED')->notice(
            '@job_ids : Zip file is extracted and items are queued for import.',
            [
              '@job_ids' => $job_info['job_id'] . '_' . $job_info['tjid'],
            ]
        );
      // Release memory.
      unset($job);
      unset($translator);
      unset($job_info);
      unset($spfilearray);
      unset($fcontent);
      unset($spfile);
      unset($fileApi);
      unset($this->isAutoAccept);
      unset($this->capiToken);
      // Collect garbage.
      gc_collect_cycles();
      return;
    }
    // If file is not zip then proceed to step 4 else skip.
    // Step 4: Approve the item status in CAPI and processed to 1 in DB.
    $this->approveItemStatusToCapiAndConnector($job_info['rid'], $job_info['job_id'], [$job_info['request_id']]);
    // Release memory.
    unset($job);
    unset($translator);
    unset($job_info);
    unset($spfilearray);
    unset($fcontent);
    unset($spfile);
    unset($fileApi);
    unset($this->isAutoAccept);
    unset($this->capiToken);
    // Collect garbage.
    gc_collect_cycles();

  }

  /**
   * Function to import Job.
   *
   * @param \drupal\tmgmt\JobInterface $job
   *   Jobs which nees to import.
   * @param string $filedatastring
   *   File content to process.
   * @param string $name
   *   File name to import the job.
   * @param string $update_id
   *   Unique update id for the job.
   * @param int $rid
   *   Unique column id.
   */
  protected function importJob(JobInterface $job, string $filedatastring, string $name, string $update_id = '', int $rid = 0) {
    $fileRepository = \Drupal::service('file.repository');
    $fileSystem = \Drupal::service('file_system');
    try {
      $path = $job->getSetting('scheme') . self::PUBLIC_RECEIVED_FILE_PATH . $name;
      $dirname = dirname($path);
      // If not able to create directory return.
      if (!$fileSystem->prepareDirectory($dirname, FileSystemInterface::CREATE_DIRECTORY)) {
        return;
      }
      if ($filedatastring === FALSE || $filedatastring === "") {
        $this->logger->get('TMGMT_CONTENTAPI_FILE_RETRIEVE_FAILED')->error(
              'Failed to get file for item: @filename, import aborted.',
              [
                '%filename' => json_encode($name),
              ]
          );
        return;
      }
      // Write the file to the directory.
      $file = $fileRepository->writeData($filedatastring, $path, FileSystemInterface::EXISTS_REPLACE);
      unset($filedatastring);
      if (!$file) {
        $this->logger->get('TMGMT_CONTENTAPI_IMPORT_WRITE_FILE_FAILED')->notice(
              'File not exist: @path',
              [
                '@path' => $path,
              ]
          );
        return;
      }
      $mimetype = $file->getMimeType();
      $filearray = NULL;
      // If file is zip then extract file else add the file directly to the array.
      if ($mimetype == 'application/zip') {
        $pathtoextract = $job->getSetting(name: 'scheme') . self::PUBLIC_RECEIVED_FILE_PATH . pathinfo($path)['filename'];
        $filearray = $this->generateFileArrayfromZip($file, $path, $pathtoextract);
        $is_zip = TRUE;
        $is_manual = FALSE;
        $manual_queue_name = \Drupal::service('tmgmt_contentapi.import_job')::QUEUE_NAME_IMPORT_JOBS_MANUALLY;
        foreach ($filearray as $item_file) {
          // Create manual import data.
          // Pass job as object.
          $file_info = [
            'rid' => $rid,
            'job_id' => $job->id(),
            'file' => $item_file,
            'iszip' => $is_zip,
            'zip_file_path' => $file->getFileUri(),
            'extracted_folder_path' => $pathtoextract,
            'is_manual' => $is_manual,
          ];
          // Add job and file details in queue.
          \Drupal::service('queue')->get($manual_queue_name)->createItem($file_info);
        }
        // Set all items in queue.
        $this->capiDataProcessor->setRequestItemInQueueStatusAsPerUpdateId($update_id, $this->capiDataProcessor::IN_QUEUE);
        return "zip_extracted_items_queued";
      }
      else {
        $filearray = [$file];
      }
      unset($file);
      // If file array is empty return.
      if (empty($filearray)) {
        $this->logger->get('TMGMT_CONTENTAPI_IMPORT_WRITE_FILE')->notice('Returning due to blank file array');
        return;
      }

      foreach ($filearray as $fileitem) {
        $plugin = new Xliff();
        if ($plugin) {
          // Validate the file on job.
          $validated_job = $plugin->validateImport($fileitem->getFileUri(), $job);
          if (!$validated_job) {
            $this->logger->get('TMGMT_CONTENTAPI')->error(
                  'Failed to validate file %FILE for job %JOB, import aborted.',
                  [
                    '%JOB' => $job->label(),
                    '%FILE' => $fileitem->getFileName(),
                  ]
              );
            $job->addMessage('Failed to validate file, import aborted.', [], 'error');
          }
          elseif ($validated_job->id() != $job->id()) {
            $this->logger->get('TMGMT_CONTENTAPI')->notice(
                  'The imported file job id %file_id does not match the job id %job_id.',
                  [
                    '%file_id' => $validated_job->id(),
                    '%job_id' => $job->id(),
                  ]
                        );
            $job->addMessage(
                            'The imported file job id @file_id does not match the job id @job_id.',
                            [
                              '@file_id' => $validated_job->id(),
                              '@job_id' => $job->id(),
                            ],
                            'error'
                        );
          }
          else {
            try {
              // Validation successful, start import.
              // TODO: Check if it makes sense to check only the active state here?
              \Drupal::service('tmgmt_contentapi.job_helper')->resetJobandItemsToActive($job, $fileitem);
              // Add translated data to the job.
              $job->addTranslatedData($plugin->import($fileitem->getFileUri()));
              $this->logger->get('TMGMT_CONTENTAPI')->notice(
                    'Successfully imported file %file_id for job %job_id.',
                    [
                      '%file_id' => $fileitem->getFileName(),
                      '%job_id' => $job->label(),
                    ]
                );
              $job->addMessage('File @filename imported successfully', ['@filename' => $fileitem->getFileName()]);
            }
            catch (\Exception $e) {
              $this->logger->get('TMGMT_CONTENTAPI')->error(
                    'File import for job %JOB failed with the following message: %message',
                    [
                      '%JOB' => $job->label(),
                      '%message' => $e->getMessage(),
                    ]
                            );
              $msg = 'File import failed with the following message: ' . $e->getMessage();
              if (strlen($msg) > 200) {
                $msg = substr($msg, 0, 200);
              }
              $job->addMessage($msg, [], 'error');
            }
          }
        }
      }
      unset($filearray);
      unset($filedatastring);
      unset($fileRepository);
      unset($fileSystem);
      gc_collect_cycles();
    }
    catch (\Exception $ep) {
      throw $ep;
    }
  }

  /**
   * Function to cp create file object from stdclass.
   *
   * @param array $filearray
   *   Array of file object.
   *
   * @return array
   *   Array of file object.
   */
  protected function cpcreateFileObjectFromStdClass(array $filearray) {
    $toreturn = [];
    foreach ($filearray as $fl) {
      $fileMime = \Drupal::service('file.mime_type.guesser')->guessMimeType($fl->uri);
      $file = File::create(
            [
            'uid' => \Drupal::currentUser()->id(),
            'filename' => \Drupal::service('file_system')->basename($fl->filename),
            'uri' => $fl->uri,
            'filemime' => $fileMime,
            'filesize' => filesize($fl->uri),
            'status' => 1
            ]
        );
      $file->save();
      array_push($toreturn, $file);
    }
    return $toreturn;
  }

  /**
   * Summary of approveItemStatusToCapiAndConnector.
   *
   * @param int $rid
   *   Unique column id.
   * @param string $jobid
   *   Capi job id.
   * @param array $request_id_array
   *   Array of request id.
   */
  public function approveItemStatusToCapiAndConnector(int $rid, string $jobid, array $request_id_array) {
    $requestApi = new RequestApi();
    $arrayOfRequestId = new ArrayOfRequestIds(['request_ids' => $request_id_array]);
    // If autoaccept set then process the job and send response as TRANSLATION_APPROVED.
    if ($this->isAutoAccept) {
      $returnarray = $requestApi->jobsJobIdRequestsApprovePut($this->capiToken, $jobid, $arrayOfRequestId);
      if (isset($returnarray)) {
        // Update tmgmt_capi_request_processor is processed status to COMPLETED.
        $this->capiDataProcessor->setRequestProgressStatus($rid, $this->capiDataProcessor::COMPLETED);
      }
      else {
        \Drupal::messenger()->addMessage('Failed to update status job for jobid: ' . $jobid, 'error');
      }
    }
    else {
      // Update tmgmt_capi_request_processor is processed status to IMPORTED.
      $this->capiDataProcessor->setRequestProgressStatus($rid, $this->capiDataProcessor::IMPORTED);
    }
    unset($requestApi);
    unset($arrayOfRequestId);
  }

  /**
   * Function to import job via xlf file.
   *
   * @param int $jid
   *   Job id.
   * @param object $file
   *   File object.
   * @param bool $iszip
   *   Is zip file.
   * @param string $zip_file_path
   *   Zip file path.
   * @param string $extracted_folder_path
   *   Extracted folder path.
   * @param bool $ismanual
   *   Is manual import.
   */
  public function importJobViaFile($jid, $file, $iszip, $zip_file_path, $extracted_folder_path, $ismanual = FALSE) {
    if (!$file) {
      return;
    }
    $job = Job::load($jid);
    $plugin = new Xliff();
    if ($plugin) {
      // Validate the file on job.
      $validated_job = $plugin->validateImport($file->getFileUri(), $job);
      if (!$validated_job) {
        $job->addMessage('Failed to validate file, import aborted.', [], 'error');
      }
      elseif ($validated_job->id() != $job->id()) {
        $job->addMessage(
              'The imported file job id @file_id does not match the job id @job_id.',
              [
                '@file_id' => $validated_job->id(),
                '@job_id' => $job->id(),
              ],
              'error'
                  );
      }
      else {
        try {
          // Generate token.
          $translator = $job->getTranslator();
          $this->capiToken = \DRUPAL::service('tmgmt_contentapi.capi_details')->getCapiToken($translator);
          // Validation successful, start import.
          $this->isAutoAccept = $translator->isAutoAccept();
          // Activate only those item id for which request has come.
          $item_ids = \Drupal::service('tmgmt_contentapi.job_helper')->resetJobandItemsToActive($job, $file);
          $capi_job_id = \Drupal::service('tmgmt_contentapi.job_helper')->getCpJobIdfromLocJob($job);
          $job->addTranslatedData($plugin->import($file->getFileUri()));
          // Approve item in CAPI and add data in processor.
          $this->checkJobFinishAndApproveRemote($item_ids, $capi_job_id, $ismanual);
          $file->delete();

          // Get all items for this job.
          $queue_items = $this->queueOperations->getQueueItems(self::QUEUE_NAME_IMPORT_JOBS_MANUALLY, 'job_id');
          $current_job_id = [$jid];
          $specific_job_array = array_intersect($queue_items, $current_job_id);
          // Check number of items remain for this job. If last item then remove the temporary zip file.
          if ($iszip && count($specific_job_array) == 1) {
            $fileSystem = \Drupal::service('file_system');
            $fileSystem->delete($zip_file_path);
            // Remove extracted folder using recursive delete.
            $fileSystem->deleteRecursive($extracted_folder_path);
          }
        }
        catch (\Exception $e) {
          $msg = 'File import failed with the following message: ' . $e->getMessage();
          if (strlen($msg) > 200) {
            $msg = substr($msg, 0, 200);
          }
          $job->addMessage($msg, [], 'error');
        }
      }
      tmgmt_write_request_messages($job);
    }

  }

  /**
   * One of the options to user to directly fetch request details from CAPI and process.
   *
   * @param int $tjid
   *   Job id.
   */
  public function failSafeImport($tjid) {
    $requestApi = new RequestApi();
    // Load Job.
    $job = Job::load($tjid);
    if (!$job) {
      return;
    }
    $translator = $job->getTranslator();
    $this->capiToken = \DRUPAL::service('tmgmt_contentapi.capi_details')->getCapiToken($translator);
    // Load job data.
    $jobcpsettings = unserialize($job->getSetting('capi-remote'));
    $first_key = !empty($jobcpsettings) ? array_key_first($jobcpsettings) : null;
    // Get CAPI job id.
    $capi_job_id = $jobcpsettings[$first_key][0]->getJobId();
    // Get all request id under this job directly from CAPI.
    $requests = $requestApi->jobsJobIdRequestsGet($this->capiToken, $capi_job_id);
    // Process each request and add it to processor.
    foreach ($requests as $req) {
      $native_ids = explode("_", $req->getSourceNativeId());
      // Set status as per the status code.
      $status = $this->capiDataProcessor::TO_PROCESS;
      // To make sure job item get import at any status, we need to reset job status to active.
      if ($req->getStatusCode() == "REVIEW_TRANSLATION" || ($tjid != '' && ($req->getStatusCode() == "TRANSLATION_APPROVED" || $req->getStatusCode() == "COMPLETED"))) {
        if ($job->getState() == Job::STATE_FINISHED) {
          $job->setState(Job::STATE_ACTIVE);
        }
      }
      // If status is othere than below then mark it as IGNORED.
      if (in_array($req->getStatusCode(),
      [
        'CREATED',
        'SENDING',
        'SENT_TO_PROVIDER',
        'IN_TRANSLATION',
        'CANCELLED',
      ])) {
        $status = $this->capiDataProcessor::IGNORED;
      }
      $job_info = [
        'update_id' => 'Safe Fail',
        'job_id' => $req->getJobId(),
        'requestid' => $req->getRequestId(),
        'status_code' => $req->getStatusCode(),
        'update_time' => $req->getModifiedDate(),
        'has_error' => ($req->getHasError()) ? 1 : 0,
        'error_message' => $req->getLatestErrorMessage(),
      ];
      $request_details_processor = $this->capiDataProcessor->getRequestDetailFromProcessor($req->getRequestId(), $capi_job_id);
      foreach ($request_details_processor as $request_details) {
        $job_info['providerid'] = $request_details->providerid;
        // Convert native id array to object for insertion.
        $tmgmtids = (object) [
          'tjid' => $native_ids[0],
          'tjiid' => $request_details->tjiid,
          'providerid' => $request_details->providerid,
        ];
        // Mark last latest entry to IGNORE in Processor.
        $this->capiDataProcessor->updatePreviousRequestStatusToNew($tmgmtids->tjid, $tmgmtids->tjiid, $req->getRequestId(), $this->capiDataProcessor::IGNORED);
        // Insert new record in data processor.
        $this->capiDataProcessor->insertRequestRecords($tmgmtids, $req->getRequestId(), $job_info, FALSE, $status);
      }
    }
    // Update status of all requests.
    $this->initiateImport($tjid);
  }

  /**
   * Function to check job finish and approve remote.
   *
   * @param array $item_ids
   *   Job object.
   * @param string $capi_job_id
   *   Capi job id.
   * @param bool $is_manual
   *   Is manual import.
   */
  public function checkJobFinishAndApproveRemote(array $item_ids, string $capi_job_id, bool $is_manual = FALSE) {
    $drupalDateTime = new DrupalDateTime('now', 'UTC');
    $requestApi = new RequestApi();
    $processor_details = $this->capiDataProcessor->getCapiProcessorDetailsBasisOftjid($item_ids);
    // If file comes here via auto import.
    foreach ($item_ids as $item_id) {
      // Get all tmgmt ids.
      $tmgmtids = (object) [
        'tjid' => $processor_details[$item_id]->tjid,
        'tjiid' => $item_id,
        'providerid' => $processor_details[$item_id]->providerid,
      ];
      // Generate all details regarding item to insert in processor.
      $job_info = [
        'update_id' => 'Manual',
        'job_id' => $processor_details[$item_id]->jobid,
        'requestid' => $processor_details[$item_id]->requestid,
        'status_code' => 'REVIEW_TRANSLATION',
        'update_time' => $drupalDateTime->modify('-5 minute'),
        'has_error' => 0,
        'error_message' => '',
      ];
      // Check if auto accept is set then mark status as COMPLETED.
      $item_status = $this->isAutoAccept ? $this->capiDataProcessor::COMPLETED : $this->capiDataProcessor::IMPORTED;
      if ($is_manual) {
        // Mark last latest entry to IGNORE in Processor.
        $this->capiDataProcessor->updatePreviousRequestStatusToNew($tmgmtids->tjid, $tmgmtids->tjiid, $processor_details[$item_id]->requestid, $this->capiDataProcessor::IGNORED);
        // Insert new record in data processor.
        $this->capiDataProcessor->insertRequestRecords($tmgmtids, $processor_details[$item_id]->requestid, $job_info, FALSE, $item_status);
      }
      else {
        $this->capiDataProcessor->updatePreviousRequestStatusToNew($tmgmtids->tjid, $tmgmtids->tjiid, $processor_details[$item_id]->requestid, $item_status);
      }
    }
    // Fetch unique request id to approve the status in CAPI. This will handle both single and multiple request id.
    $request_id_array = array_unique(array_column($processor_details, 'requestid'));
    $arrayOfRequestId = new ArrayOfRequestIds(['request_ids' => $request_id_array]);
    // If autoaccept set then process the job and send response as TRANSLATION_APPROVED.
    if ($this->isAutoAccept) {
      $requestApi->jobsJobIdRequestsApprovePut($this->capiToken, $capi_job_id, $arrayOfRequestId);
    }
    unset($requestApi);
  }

  /**
   * Function to generate file array from extracted zip.
   *
   * @param \Drupal\file\Entity\File $file
   *   Array of file object.
   * @param string $path
   *   Path of the file.
   * @param string $pathtoextract
   *   Path to extract the file.
   *
   * @return array
   *   Array of file object.
   */
  public function generateFileArrayfromZip(File $file, string $path, string $pathtoextract) {
    $fileSystem = \Drupal::service('file_system');
    $ziparchive = new \ZipArchive();
    $openachresult = $ziparchive->open($fileSystem->realpath($path));
    if ($openachresult) {
      if ($ziparchive->extractTo($fileSystem->realpath($pathtoextract))) {
        $file->delete();
        $filearray = $this->cpcreateFileObjectFromStdClass($fileSystem->scanDirectory($pathtoextract, '/.*\.xlf$/'));
      }
    }
    // Cloase the zip archive.
    $ziparchive->close();
    return $filearray;
  }

  /**
   * Function to calculate remaining items in perticular queue for a job.
   *
   * @param int $tjid
   *   Job id.
   * @param string $queue_name
   *   Queue name.
   */
  public function calculateRemainingItems(int $tjid, string $queue_name) {
    // Get all items from job.
    $job = Job::load($tjid);
    if (!$job) {
      return 0;
    }
    // Get all items for this job.
    $total_items = $job->getItems();
    $queue_items = $this->queueOperations->getQueueItems($queue_name, 'job_id', TRUE);

    $current_job_id = [$tjid];
    $remaining_items = array_intersect($queue_items, $current_job_id);
    if (empty($remaining_items)) {
      return [
        'total_items' => count($total_items),
        'remaining_items' => 0,
        'allowed_upload' => TRUE,
      ];
    }

    return [
      'total_items' => count($total_items),
      'remaining_items' => count($total_items) - count($remaining_items),
      'allowed_upload' => FALSE,
    ];

  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc