You are here

abstract class DatabaseFileUtilityBase in Smart IP 8.2

Same name and namespace in other branches
  1. 8.4 src/DatabaseFileUtilityBase.php \Drupal\smart_ip\DatabaseFileUtilityBase
  2. 8.3 src/DatabaseFileUtilityBase.php \Drupal\smart_ip\DatabaseFileUtilityBase

Database file utility methods class wrapper.

@package Drupal\smart_ip

Hierarchy

Expanded class hierarchy of DatabaseFileUtilityBase

File

src/DatabaseFileUtilityBase.php, line 18
Contains \Drupal\smart_ip\DatabaseFileUtilityBase.

Namespace

Drupal\smart_ip
View source
abstract class DatabaseFileUtilityBase implements DatabaseFileUtilityInterface {

  /**
   * Download Smart IP's data source module's database timout.
   */
  const DOWNLOAD_TIMEOUT = 600;

  /**
   * Fixed Drupal folder path of Smart IP data source module's database file is
   * stored.
   */
  const DRUPAL_FOLDER = 'private://smart_ip';

  /**
   * Download Smart IP's data source module's database file weekly.
   */
  const DOWNLOAD_WEEKLY = 0;

  /**
   * Download Smart IP's data source module's database file monthly.
   */
  const DOWNLOAD_MONTHLY = 1;

  /**
   * @var \Drupal\smart_ip\SmartIpDataSourceInterface
   */
  protected $dataSource;

  /**
   * Constructs Smart IP's data source module's database file utility.
   *
   * @param \Drupal\smart_ip\SmartIpDataSourceInterface $dataSource
   */
  public function __construct(SmartIpDataSourceInterface $dataSource) {
    $this->dataSource = $dataSource;
  }

  /**
   * Get Smart IP's data source module's database file's path. This should
   * return the fixed Drupal folder if auto update is on or if custom path is
   * empty with auto update off.
   *
   * @param bool $autoUpdate
   * @param string $customPath
   * @return string
   */
  public static function getPath($autoUpdate, $customPath) {
    if ($autoUpdate == TRUE || $autoUpdate == FALSE && empty($customPath)) {

      /** @var \Drupal\Core\File\FileSystem $filesystem */
      $filesystem = \Drupal::service('file_system');
      return $filesystem
        ->realpath(self::DRUPAL_FOLDER);
    }
    return $customPath;
  }

  /**
   * {@inheritdoc}
   */
  public static function needsUpdate($autoUpdate = TRUE, $frequency = self::DOWNLOAD_MONTHLY) {
    if ($autoUpdate) {
      $timeNow = strtotime('midnight', REQUEST_TIME);
      $lastUpdateTime = \Drupal::state()
        ->get('smart_ip_maxmind_geoip2_bin_db.last_update_time') ?: 0;
      $lastUpdateTime = strtotime('midnight', $lastUpdateTime);
      if ($frequency == self::DOWNLOAD_WEEKLY) {
        $wednesday = strtotime('first Wednesday', $timeNow);
        if ($wednesday <= $timeNow && $wednesday > $lastUpdateTime) {
          return TRUE;
        }
      }
      elseif ($frequency == self::DOWNLOAD_MONTHLY) {
        $firstWed = strtotime('first Wednesday of this month', $timeNow);
        if ($firstWed <= $timeNow && $firstWed > $lastUpdateTime) {
          return TRUE;
        }
      }
    }
    return FALSE;
  }

  /**
   * Download Smart IP's data source module's database file and extract it.
   *
   * @param string $url
   *   URL of the Smart IP's data source module's service provider.
   * @param string $file
   *   File name of the Smart IP's data source module's database including its
   *   extension name.
   * @param string $sourceId
   *   Smart IP data source module's source ID.
   * @return bool
   *   Returns FALSE if process failed.
   */
  protected static function requestDatabaseFile($url, $file, $sourceId) {

    /** @var \Drupal\Core\File\FileSystem $filesystem */
    $filesystem = \Drupal::service('file_system');
    $realDestination = $filesystem
      ->realpath(self::DRUPAL_FOLDER);
    $success = file_prepare_directory($realDestination, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
    if ($success) {
      $downloadCacheDirectory = _update_manager_cache_directory() . '/';
      $realDownloadCache = $filesystem
        ->realpath("{$downloadCacheDirectory}{$file}");
      if (file_exists($realDownloadCache)) {

        // Remove old database file from temp download directory if still exist.
        $filesystem
          ->unlink($realDownloadCache);
      }

      // Download the Smart IP's data source module's database file.

      /** @var \Drupal\Core\Http\ClientFactory $client */
      $client = \Drupal::service('http_client_factory');
      $data = $client
        ->fromOptions([
        'timeout' => self::DOWNLOAD_TIMEOUT,
      ])
        ->get($url)
        ->getBody();
      $parsedUrl = parse_url($url);
      $localPath = $downloadCacheDirectory . $filesystem
        ->basename($parsedUrl['path']);
      $localCache = file_unmanaged_save_data($data, $localPath, FILE_EXISTS_REPLACE);
      if (!$localCache || $downloadCacheDirectory == $localCache) {
        $message = t('Failed to download %source.', array(
          '%source' => $url,
        ));
        \Drupal::state()
          ->set('smart_ip.request_db_error_source_id', $sourceId);
        \Drupal::state()
          ->set('smart_ip.request_db_error_message', $message);
        \Drupal::logger('smart_ip')
          ->error($message);
        return FALSE;
      }
      $extractDirectory = _update_manager_extract_directory();
      $realExtractDirectory = $filesystem
        ->realpath($extractDirectory);
      $realLocalCache = $filesystem
        ->realpath($localCache);
      $targetFile = "{$realExtractDirectory}/{$file}";
      if (file_exists($targetFile)) {

        // Remove old database file from temp extract directory if still exist.
        $filesystem
          ->unlink($targetFile);
      }

      // Extract it.
      try {
        module_load_include('inc', 'update', 'update.manager');
        update_manager_archive_extract($localCache, $extractDirectory);
      } catch (\Exception $e) {
        $extractError = TRUE;
        \Drupal::logger('smart_ip')
          ->debug($e
          ->getMessage());
        if (class_exists('PharData')) {
          try {
            $extractError = FALSE;
            $archive = new \PharData($realLocalCache);
            $archive
              ->extractTo($realExtractDirectory);
          } catch (\Exception $e) {
            \Drupal::logger('smart_ip')
              ->debug($e
              ->getMessage());
            if (!file_exists($targetFile)) {
              $extractError = TRUE;
            }
          }
        }
        if ($extractError) {
          $sourceFp = gzopen($realLocalCache, 'rb');
          $targetFp = fopen($targetFile, 'w');
          while (!gzeof($sourceFp)) {
            $data = gzread($sourceFp, 4096);
            fwrite($targetFp, $data, strlen($data));
          }
          gzclose($sourceFp);
          fclose($targetFp);
        }
      }

      // Verify it.
      if (!file_exists($targetFile)) {
        $message = t('Failed extracting %file.', array(
          '%file' => $realLocalCache,
        ));
        \Drupal::state()
          ->set('smart_ip.request_db_error_source_id', $sourceId);
        \Drupal::state()
          ->set('smart_ip.request_db_error_message', $message);
        \Drupal::logger('smart_ip')
          ->error($message);
        return FALSE;
      }

      // Delete the old Smart IP data source module's database file.
      $filesystem
        ->unlink("{$realDestination}/{$file}");
      if (file_unmanaged_move($targetFile, $realDestination) === FALSE) {
        $message = t('The file %file could not be moved to %destination.', array(
          '%file' => $targetFile,
          '%destination' => $realDestination,
        ));
        \Drupal::state()
          ->set('smart_ip.request_db_error_source_id', $sourceId);
        \Drupal::state()
          ->set('smart_ip.request_db_error_message', $message);
        \Drupal::logger('smart_ip')
          ->error($message);
        return FALSE;
      }
      else {

        // Success! Clear error flag and message.
        \Drupal::state()
          ->set('smart_ip.request_db_error_source_id', '');
        \Drupal::state()
          ->set('smart_ip.request_db_error_message', '');
        \Drupal::logger('smart_ip')
          ->info(t('The database file %file successfully downloaded to %destination', array(
          '%file' => $file,
          '%destination' => $realDestination,
        )));
      }
    }
    else {
      $message = t('Your private file system path is not yet configured. Please check your @filesystem.', array(
        '@filesystem' => Link::fromTextAndUrl(t('File system'), Url::fromRoute('system.file_system_settings'))
          ->toString(),
      ));
      \Drupal::state()
        ->set('smart_ip.request_db_error_source_id', $sourceId);
      \Drupal::state()
        ->set('smart_ip.request_db_error_message', $message);
      return FALSE;
    }
    return TRUE;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DatabaseFileUtilityBase::$dataSource protected property
DatabaseFileUtilityBase::DOWNLOAD_MONTHLY constant Download Smart IP's data source module's database file monthly.
DatabaseFileUtilityBase::DOWNLOAD_TIMEOUT constant Download Smart IP's data source module's database timout.
DatabaseFileUtilityBase::DOWNLOAD_WEEKLY constant Download Smart IP's data source module's database file weekly.
DatabaseFileUtilityBase::DRUPAL_FOLDER constant Fixed Drupal folder path of Smart IP data source module's database file is stored.
DatabaseFileUtilityBase::getPath public static function Get Smart IP's data source module's database file's path. This should return the fixed Drupal folder if auto update is on or if custom path is empty with auto update off. Overrides DatabaseFileUtilityInterface::getPath
DatabaseFileUtilityBase::needsUpdate public static function Checks if Smart IP's data source module's database file needs update. Overrides DatabaseFileUtilityInterface::needsUpdate
DatabaseFileUtilityBase::requestDatabaseFile protected static function Download Smart IP's data source module's database file and extract it.
DatabaseFileUtilityBase::__construct public function Constructs Smart IP's data source module's database file utility.
DatabaseFileUtilityInterface::getFilename public static function Get Smart IP's data source module's database filename.