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,
];
}
}
