You are here

protected function ContextUploader::uploadContextMissingResources in TMGMT Translator Smartling 8.4

Same name and namespace in other branches
  1. 8.2 src/Context/ContextUploader.php \Drupal\tmgmt_smartling\Context\ContextUploader::uploadContextMissingResources()
  2. 8.3 src/Context/ContextUploader.php \Drupal\tmgmt_smartling\Context\ContextUploader::uploadContextMissingResources()

Parameters

$smartling_context_directory:

$proj_settings:

1 call to ContextUploader::uploadContextMissingResources()
ContextUploader::upload in src/Context/ContextUploader.php

File

src/Context/ContextUploader.php, line 222

Class

ContextUploader

Namespace

Drupal\tmgmt_smartling\Context

Code

protected function uploadContextMissingResources($smartling_context_directory, $proj_settings) {

  // Cache for resources which we can't upload. Do not try to re-upload them
  // for 1 hour. After 1 hour cache will be reset and we will try again.
  $cache_name = 'smartling_context_resources_cache';
  $time_to_live = 60 * 60;
  $two_days = 2 * 24 * 60 * 60;
  $cache = \Drupal::cache()
    ->get($cache_name);
  $cached_data = empty($cache) ? [] : $cache->data;
  $update_cache = FALSE;
  $smartling_context_resources_directory = $smartling_context_directory . '/resources';

  // Do nothing if directory for resources isn't accessible.
  if (!\Drupal::service('file_system')
    ->prepareDirectory($smartling_context_resources_directory, FileSystemInterface::CREATE_DIRECTORY)) {
    $this->logger
      ->error("Context resources directory @dir doesn't exist or is not writable. Missing resources were not uploaded. Context might look incomplete.", [
      '@dir' => $smartling_context_directory,
    ]);
    return;
  }
  try {
    $api = $this
      ->getApiWrapper($proj_settings)
      ->getApi('context');
    $time_out = PHP_SAPI == 'cli' ? 300 : 30;
    $start_time = time();
    do {
      $delta = time() - $start_time;
      if ($delta > $time_out) {
        throw new SmartlingApiException(vsprintf('Not all context resources are uploaded after %s seconds.', [
          $delta,
        ]));
      }
      $all_missing_resources = $api
        ->getAllMissingResources();

      // Method getAllMissingResources can return not all missing resources
      // in case it took to much time. Log this information.
      if (!$all_missing_resources['all']) {
        $this->logger
          ->warning('Not all missing context resources are received. Context might look incomplete.');
      }
      $fresh_resources = [];
      foreach ($all_missing_resources['items'] as $item) {
        if (!in_array($item['resourceId'], $cached_data)) {
          $fresh_resources[] = $item;
        }
      }

      // Walk through missing resources and try to upload them.
      foreach ($fresh_resources as $item) {
        if (time() - strtotime($item['created']) >= $two_days) {
          $update_cache = TRUE;
          $cached_data[] = $item['resourceId'];
          continue;
        }

        // If current resource isn't in the cache and it's accessible then
        // it means we can try to upload it.
        if (!in_array($item['resourceId'], $cached_data) && $this->assetInliner
          ->remote_file_exists($item['url'], $proj_settings)) {
          $smartling_context_resource_file = $smartling_context_resources_directory . '/' . $item['resourceId'];
          $smartling_context_resource_file_content = $this->assetInliner
            ->getUrlContents($item['url'], 0, 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10', $proj_settings);

          // Ensure that resources directory is accessible, resource
          // downloaded properly and only then upload it. ContextAPI will not
          // be able to fopen() resource which is behind basic auth. So
          // download it first (with a help of curl), save it to smartling's
          // directory and then upload.
          if ($file = file_save_data($smartling_context_resource_file_content, $smartling_context_resource_file, FileSystemInterface::EXISTS_REPLACE)) {
            $stream_wrapper_manager = \Drupal::service('stream_wrapper_manager')
              ->getViaUri($file
              ->getFileUri());
            $params = new UploadResourceParameters();
            $params
              ->setFile($stream_wrapper_manager
              ->realpath());
            $actual_file_size = $file
              ->getSize();
            if ($actual_file_size <= ContextUploader::FILE_SIZE_LIMIT) {
              $is_resource_uploaded = $api
                ->uploadResource($item['resourceId'], $params);
            }
            else {
              $is_resource_uploaded = FALSE;
              $this->logger
                ->warning("Context resource file exceeds its maximum permitted_size = @permitted_size, actual_size = @actual_size, id = @id and url = @url", [
                '@permitted_size' => ContextUploader::FILE_SIZE_LIMIT,
                '@actual_size' => $actual_file_size,
                '@id' => $item['resourceId'],
                '@url' => $item['url'],
              ]);
            }

            // Resource isn't uploaded for some reason. Log this info and set
            // resource id into the cache. We will not try to upload this
            // resource for the next hour.
            if (!$is_resource_uploaded) {
              $update_cache = TRUE;
              $cached_data[] = $item['resourceId'];
              $this->logger
                ->warning("Can't upload context resource file with id = @id and url = @url. Context might look incomplete.", [
                '@id' => $item['resourceId'],
                '@url' => $item['url'],
              ]);
            }
          }
          else {
            $this->logger
              ->error("Can't save context resource file: @path", [
              '@path' => $smartling_context_resource_file,
            ]);
          }
        }
        else {

          // Current resource isn't accessible (or already in the cache).
          // If first case then add inaccessible resource into the cache.
          if (!in_array($item['resourceId'], $cached_data)) {
            $update_cache = TRUE;
            $cached_data[] = $item['resourceId'];
          }
        }
      }

      // Set failed resources into the cache for the next hour.
      if ($update_cache) {
        \Drupal::cache()
          ->set($cache_name, $cached_data, time() + $time_to_live);
      }
    } while (!empty($fresh_resources));
  } catch (Exception $e) {
    watchdog_exception('tmgmt_smartling', $e);
  }
}