You are here

class SmartIpEventSubscriber in Smart IP 8.3

Same name in this branch
  1. 8.3 modules/device_geolocation/src/EventSubscriber/SmartIpEventSubscriber.php \Drupal\device_geolocation\EventSubscriber\SmartIpEventSubscriber
  2. 8.3 modules/smart_ip_maxmind_geoip2_bin_db/src/EventSubscriber/SmartIpEventSubscriber.php \Drupal\smart_ip_maxmind_geoip2_bin_db\EventSubscriber\SmartIpEventSubscriber
  3. 8.3 modules/smart_ip_ipinfodb_web_service/src/EventSubscriber/SmartIpEventSubscriber.php \Drupal\smart_ip_ipinfodb_web_service\EventSubscriber\SmartIpEventSubscriber
  4. 8.3 modules/smart_ip_ip2location_bin_db/src/EventSubscriber/SmartIpEventSubscriber.php \Drupal\smart_ip_ip2location_bin_db\EventSubscriber\SmartIpEventSubscriber
  5. 8.3 modules/smart_ip_abstract_web_service/src/EventSubscriber/SmartIpEventSubscriber.php \Drupal\smart_ip_abstract_web_service\EventSubscriber\SmartIpEventSubscriber
  6. 8.3 modules/smart_ip_maxmind_geoip2_web_service/src/EventSubscriber/SmartIpEventSubscriber.php \Drupal\smart_ip_maxmind_geoip2_web_service\EventSubscriber\SmartIpEventSubscriber
Same name and namespace in other branches
  1. 8.4 modules/smart_ip_maxmind_geoip2_bin_db/src/EventSubscriber/SmartIpEventSubscriber.php \Drupal\smart_ip_maxmind_geoip2_bin_db\EventSubscriber\SmartIpEventSubscriber

Core functionality of this Smart IP data source module. Listens to Smart IP override events.

@package Drupal\smart_ip_maxmind_geoip2_bin_db\EventSubscriber

Hierarchy

Expanded class hierarchy of SmartIpEventSubscriber

1 file declares its use of SmartIpEventSubscriber
DatabaseFileUtility.php in modules/smart_ip_maxmind_geoip2_bin_db/src/DatabaseFileUtility.php
Contains \Drupal\smart_ip_maxmind_geoip2_bin_db\DatabaseFileUtility.
1 string reference to 'SmartIpEventSubscriber'
smart_ip_maxmind_geoip2_bin_db.services.yml in modules/smart_ip_maxmind_geoip2_bin_db/smart_ip_maxmind_geoip2_bin_db.services.yml
modules/smart_ip_maxmind_geoip2_bin_db/smart_ip_maxmind_geoip2_bin_db.services.yml
1 service uses SmartIpEventSubscriber
smart_ip_maxmind_geoip2_bin_db.smart_ip_event_subscriber in modules/smart_ip_maxmind_geoip2_bin_db/smart_ip_maxmind_geoip2_bin_db.services.yml
Drupal\smart_ip_maxmind_geoip2_bin_db\EventSubscriber\SmartIpEventSubscriber

File

modules/smart_ip_maxmind_geoip2_bin_db/src/EventSubscriber/SmartIpEventSubscriber.php, line 28
Contains \Drupal\smart_ip_maxmind_geoip2_bin_db\EventSubscriber\SmartIpEventSubscriber.

Namespace

Drupal\smart_ip_maxmind_geoip2_bin_db\EventSubscriber
View source
class SmartIpEventSubscriber extends SmartIpEventSubscriberBase {

  /**
   * {@inheritdoc}
   */
  public static function sourceId() {
    return 'maxmind_geoip2_bin_db';
  }

  /**
   * {@inheritdoc}
   */
  public static function configName() {
    return 'smart_ip_maxmind_geoip2_bin_db.settings';
  }

  /**
   * {@inheritdoc}
   */
  public function processQuery(GetLocationEvent $event) {
    if ($event
      ->getDataSource() == self::sourceId()) {
      $config = \Drupal::config(self::configName());
      $autoUpdate = $config
        ->get('db_auto_update');
      $customPath = $config
        ->get('bin_file_custom_path');
      $version = $config
        ->get('version');
      $edition = $config
        ->get('edition');
      $location = $event
        ->getLocation();
      $ipAddress = $location
        ->get('ipAddress');
      $folder = DatabaseFileUtility::getPath($autoUpdate, $customPath);
      $file = DatabaseFileUtility::getFilename($version, $edition);
      $dbFile = "{$folder}/{$file}";
      if (!file_exists($dbFile)) {
        \Drupal::logger('smart_ip')
          ->error(t('The database file %file does not exist or has been moved.', [
          '%file' => $dbFile,
        ]));
        return;
      }
      if (class_exists('\\MaxMind\\Db\\Reader')) {
        $reader = new \MaxMind\Db\Reader($dbFile);
        $raw = $reader
          ->get($ipAddress);
      }
      else {
        $reader = new \GeoIp2\Database\Reader($dbFile);
        $edition = $config
          ->get('edition');
        if ($edition == MaxmindGeoip2BinDb::COUNTRY_EDITION) {
          $record = $reader
            ->country($ipAddress);
        }
        else {
          $record = $reader
            ->city($ipAddress);
        }
        $raw = $record
          ->jsonSerialize();
      }
      $lang = \Drupal::languageManager()
        ->getCurrentLanguage()
        ->getId();
      if (class_exists('\\MaxMind\\Db\\Reader')) {
        $reader
          ->close();
      }
      if (!isset($raw['country']['names'][$lang])) {

        // The current language is not yet supported by MaxMind, use English as
        // default language.
        $lang = 'en';
      }
      $country = isset($raw['country']['names'][$lang]) ? $raw['country']['names'][$lang] : '';
      $countryCode = isset($raw['country']['iso_code']) ? $raw['country']['iso_code'] : '';
      $region = isset($raw['subdivisions'][0]['names'][$lang]) ? $raw['subdivisions'][0]['names'][$lang] : '';
      $regionCode = isset($raw['subdivisions'][0]['iso_code']) ? $raw['subdivisions'][0]['iso_code'] : '';
      $city = isset($raw['city']['names'][$lang]) ? $raw['city']['names'][$lang] : '';
      $zip = isset($raw['postal']['code']) ? $raw['postal']['code'] : '';
      $latitude = isset($raw['location']['latitude']) ? $raw['location']['latitude'] : '';
      $longitude = isset($raw['location']['longitude']) ? $raw['location']['longitude'] : '';
      $timeZone = isset($raw['location']['time_zone']) ? $raw['location']['time_zone'] : '';
      $isEuCountry = isset($raw['country']['is_in_european_union']) ? $raw['country']['is_in_european_union'] : '';
      $isGdprCountry = isset($record['country']['isGdprCountry']) ? $record['country']['isGdprCountry'] : '';
      $location
        ->set('originalData', $raw)
        ->set('country', $country)
        ->set('countryCode', Unicode::strtoupper($countryCode))
        ->set('region', $region)
        ->set('regionCode', $regionCode)
        ->set('city', $city)
        ->set('zip', $zip)
        ->set('latitude', $latitude)
        ->set('longitude', $longitude)
        ->set('timeZone', $timeZone)
        ->set('isEuCountry', $isEuCountry)
        ->set('isGdprCountry', $isGdprCountry);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function formSettings(AdminSettingsEvent $event) {
    $config = \Drupal::config(self::configName());
    $autoUpdate = $config
      ->get('db_auto_update');
    $form = $event
      ->getForm();

    /** @var \Drupal\Core\File\FileSystem $filesystem */
    $filesystem = \Drupal::service('file_system');
    $privateFolder = $filesystem
      ->realpath(DatabaseFileUtilityBase::DRUPAL_FOLDER);
    $errorSourceId = \Drupal::state()
      ->get('smart_ip.request_db_error_source_id') ?: '';
    $autoDbUpdateLabel = t('Automatic MaxMind GeoIP2 binary database update');
    if (!$autoUpdate && $errorSourceId == self::sourceId()) {
      $form['smart_ip_bin_database_update']['#access'] = FALSE;
    }
    if (empty($privateFolder)) {
      $privateFolder = t('your "smart_ip" labelled folder inside your Drupal private folder (currently it is not yet set)');
    }
    else {
      $privateFolder = t('@path (default)', [
        '@path' => $privateFolder,
      ]);
    }
    $form['smart_ip_data_source_selection']['smart_ip_data_source']['#options'][self::sourceId()] = t("Use MaxMind GeoIP2 binary database. It is the evolution of MaxMind's \n      original GeoIP binary database or now called GeoIP Legacy. This MaxMind's \n      binary database uses a custom binary format to maximize lookup speed and \n      accessible via two available APIs: @maxmind_db_reader_api which includes \n      an optional C extension that you may @install to dramatically increase the \n      performance of lookups in GeoIP2 binary database and the default \n      @geoip2_api. The binary database file for both lite and licensed version \n      can be downloaded @here (you will need to @login to your MaxMind account \n      first). The binary database is roughly 130MB, and there's an option below \n      to enable the automatic download/extraction of it. If you prefer to \n      manually download the file %file_lite_city (if Lite version City edition) \n      or %file_licensed_city (if Licensed version City edition) or \n      %file_lite_country (if Lite version Country edition) or \n      %file_licensed_country (if Licensed version Country edition), it must be \n      uploaded to your server at @path or to your defined custom path (Note: It \n      is your responsibility to update them manually every month and to define \n      such a path, please set '@auto_update_label' to 'No', and fill in the \n      field which will then appear).", [
      '@maxmind_db_reader_api' => Link::fromTextAndUrl(t('MaxMind DB Reader PHP API'), Url::fromUri('https://github.com/maxmind/MaxMind-DB-Reader-php'))
        ->toString(),
      '@install' => Link::fromTextAndUrl(t('install'), Url::fromUri('https://www.webfoobar.com/node/71#install-maxmind-php-c-extension'))
        ->toString(),
      '@geoip2_api' => Link::fromTextAndUrl(t('GeoIP2 PHP API'), Url::fromUri('http://maxmind.github.io/GeoIP2-php'))
        ->toString(),
      '@login' => Link::fromTextAndUrl(t('login'), Url::fromUri('https://www.maxmind.com/en/account/login'))
        ->toString(),
      '@here' => Link::fromTextAndUrl(t('here'), Url::fromUri('https://www.maxmind.com/en/download_files'))
        ->toString(),
      '%file_lite_city' => MaxmindGeoip2BinDb::FILENAME_LITE_CITY . MaxmindGeoip2BinDb::FILE_EXTENSION,
      '%file_licensed_city' => MaxmindGeoip2BinDb::FILENAME_LINCENSED_CITY . MaxmindGeoip2BinDb::FILE_EXTENSION,
      '%file_lite_country' => MaxmindGeoip2BinDb::FILENAME_LITE_COUNTRY . MaxmindGeoip2BinDb::FILE_EXTENSION,
      '%file_licensed_country' => MaxmindGeoip2BinDb::FILENAME_LINCENSED_COUNTRY . MaxmindGeoip2BinDb::FILE_EXTENSION,
      '@path' => $privateFolder,
      '@auto_update_label' => $autoDbUpdateLabel,
    ]);
    $form['smart_ip_data_source_selection']['maxmind_geoip2_bin_db_version'] = [
      '#type' => 'select',
      '#title' => t('MaxMind GeoIP2 binary database version'),
      '#description' => t('Select version of MaxMind GeoIP2 binary database.'),
      '#options' => [
        MaxmindGeoip2BinDb::LINCENSED_VERSION => t('Licensed'),
        MaxmindGeoip2BinDb::LITE_VERSION => t('Lite'),
      ],
      '#default_value' => $config
        ->get('version'),
      '#states' => [
        'visible' => [
          ':input[name="smart_ip_data_source"]' => [
            'value' => self::sourceId(),
          ],
        ],
      ],
    ];
    $form['smart_ip_data_source_selection']['maxmind_geoip2_bin_db_edition'] = [
      '#type' => 'select',
      '#title' => t('MaxMind GeoIP2 binary database edition'),
      '#description' => t('Select edition of MaxMind GeoIP2 binary database.'),
      '#options' => [
        MaxmindGeoip2BinDb::CITY_EDITION => t('City'),
        MaxmindGeoip2BinDb::COUNTRY_EDITION => t('Country'),
      ],
      '#default_value' => $config
        ->get('edition'),
      '#states' => [
        'visible' => [
          ':input[name="smart_ip_data_source"]' => [
            'value' => self::sourceId(),
          ],
        ],
      ],
    ];
    $form['smart_ip_data_source_selection']['maxmind_geoip2_bin_db_user_account'] = [
      '#type' => 'textfield',
      '#title' => t('MaxMind user account ID'),
      '#description' => t('Enter your MaxMind user account ID. This is required for
        lite version.'),
      '#default_value' => $config
        ->get('user_account'),
      '#size' => 30,
      '#states' => [
        'visible' => [
          ':input[name="smart_ip_data_source"]' => [
            'value' => self::sourceId(),
          ],
          ':input[name="maxmind_geoip2_bin_db_version"]' => [
            'value' => MaxmindGeoip2BinDb::LITE_VERSION,
          ],
          ':input[name="maxmind_geoip2_bin_db_auto_update"]' => [
            'value' => '1',
          ],
        ],
      ],
    ];
    $form['smart_ip_data_source_selection']['maxmind_geoip2_bin_db_license_key'] = [
      '#type' => 'textfield',
      '#title' => t('MaxMind GeoIP2 license key'),
      '#description' => t("Enter your MaxMind GeoIP2 account's license key (view your \n        license key @here). This is required for lite and licensed version.", [
        '@here' => Link::fromTextAndUrl(t('here'), Url::fromUri('https://www.maxmind.com/en/my_license_key'))
          ->toString(),
      ]),
      '#default_value' => $config
        ->get('license_key'),
      '#size' => 30,
      '#states' => [
        'visible' => [
          ':input[name="smart_ip_data_source"]' => [
            'value' => self::sourceId(),
          ],
          ':input[name="maxmind_geoip2_bin_db_auto_update"]' => [
            'value' => '1',
          ],
        ],
      ],
    ];
    $form['smart_ip_data_source_selection']['maxmind_geoip2_bin_db_auto_update'] = [
      '#type' => 'select',
      '#title' => $autoDbUpdateLabel,
      '#description' => t('MaxMind GeoIP2 binary database will be automatically updated via
        cron.php every Wednesday (for licensed and lite/free versions).
        MaxMind GeoIP2 updates their database every Tuesday for licensed
        and free versions. @cron must be enabled for this to work.', [
        '@cron' => Link::fromTextAndUrl(t('Cron'), Url::fromRoute('system.cron_settings'))
          ->toString(),
      ]),
      '#options' => [
        TRUE => t('Yes'),
        FALSE => t('No'),
      ],
      '#default_value' => intval($autoUpdate),
      '#states' => [
        'visible' => [
          ':input[name="smart_ip_data_source"]' => [
            'value' => self::sourceId(),
          ],
        ],
      ],
    ];
    $form['smart_ip_data_source_selection']['maxmind_geoip2_bin_db_custom_path'] = [
      '#type' => 'textfield',
      '#title' => t('MaxMind GeoIP2 binary database custom path'),
      '#description' => t('Define the path where the MaxMind GeoIP2 binary database file is
        located in your server (Note: it is your responsibility to add security
        on this path. See the online handbook for @security). Include preceding
        slash but do not include trailing slash. This is useful for multi Drupal
        sites with each of their Smart IP module looks to a common MaxMind
        GeoIP2 binary database and it can be also useful for server with
        installed GeoIPLookup CLI tool where its MaxMind binary database file
        can be used here (usually its path is located at /usr/share/GeoIP). This
        path will be ignored if "Automatic MaxMind binary database update" is
        enabled which uses the Drupal private file system path. Leave it blank
        if you prefer the default Drupal private file system path.', [
        '@security' => Link::fromTextAndUrl(t('more information about securing private files'), Url::fromUri('https://www.drupal.org/documentation/modules/file'))
          ->toString(),
      ]),
      '#default_value' => $config
        ->get('bin_file_custom_path'),
      '#states' => [
        'visible' => [
          ':input[name="smart_ip_data_source"]' => [
            'value' => self::sourceId(),
          ],
          ':input[name="maxmind_geoip2_bin_db_auto_update"]' => [
            'value' => '0',
          ],
        ],
      ],
    ];
    $event
      ->setForm($form);
  }

  /**
   * {@inheritdoc}
   */
  public function validateFormSettings(AdminSettingsEvent $event) {

    /** @var \Drupal\Core\Form\FormStateInterface $formState */
    $formState = $event
      ->getFormState();
    if ($formState
      ->getValue('smart_ip_data_source') == self::sourceId()) {
      $autoUpdate = $formState
        ->getValue('maxmind_geoip2_bin_db_auto_update');
      if ($autoUpdate && $formState
        ->getValue('maxmind_geoip2_bin_db_version') == MaxmindGeoip2BinDb::LITE_VERSION && $formState
        ->isValueEmpty('maxmind_geoip2_bin_db_user_account')) {
        $formState
          ->setErrorByName('maxmind_geoip2_bin_db_user_account', t('Please provide MaxMind GeoIP2 user account ID.'));
      }
      if ($autoUpdate && $formState
        ->getValue('maxmind_geoip2_bin_db_version') == MaxmindGeoip2BinDb::LITE_VERSION && $formState
        ->isValueEmpty('maxmind_geoip2_bin_db_license_key') || $formState
        ->getValue('maxmind_geoip2_bin_db_version') == MaxmindGeoip2BinDb::LINCENSED_VERSION && $formState
        ->isValueEmpty('maxmind_geoip2_bin_db_license_key')) {
        $formState
          ->setErrorByName('maxmind_geoip2_bin_db_license_key', t('Please provide MaxMind GeoIP2 license key.'));
      }
      if ($autoUpdate || !$autoUpdate && $formState
        ->isValueEmpty('maxmind_geoip2_bin_db_custom_path')) {
        if (empty(PrivateStream::basePath())) {
          $formState
            ->setErrorByName('maxmind_geoip2_bin_db_auto_update', t('Your private file system path is not yet configured.
              Please check your @filesystem.', [
            '@filesystem' => Link::fromTextAndUrl(t('File system'), Url::fromRoute('system.file_system_settings'))
              ->toString(),
          ]));
        }
        else {

          /** @var \Drupal\Core\File\FileSystem $filesystem */
          $filesystem = \Drupal::service('file_system');
          $privateFolder = $filesystem
            ->realpath(DatabaseFileUtilityBase::DRUPAL_FOLDER);
          $file = DatabaseFileUtility::getFilename($formState
            ->getValue('maxmind_geoip2_bin_db_version'), $formState
            ->getValue('maxmind_geoip2_bin_db_edition'));
          if (!file_exists("{$privateFolder}/{$file}")) {
            if ($autoUpdate) {
              if (empty($privateFolder)) {
                $message = t('There is an @issue in Drupal private file system path.', [
                  '@issue' => Link::fromTextAndUrl(t('issue'), Url::fromRoute('system.status', [], [
                    'fragment' => 'error',
                  ]))
                    ->toString(),
                ]);
              }
              else {
                $message = t('Initially you need to manually download the @file and
                   upload it to your server at @path. The next succeeding
                   updates should be automatic.', [
                  '@file' => $file,
                  '@path' => $privateFolder,
                ]);
              }
            }
            else {
              $message = t('Please upload the @file at @path.', [
                '@file' => $file,
                '@path' => $privateFolder,
              ]);
            }
            $formState
              ->setErrorByName('maxmind_geoip2_bin_db_auto_update', $message);
          }
        }
      }
      elseif (!$formState
        ->isValueEmpty('maxmind_geoip2_bin_db_custom_path')) {
        $folder = $formState
          ->getValue('maxmind_geoip2_bin_db_custom_path');
        $file = DatabaseFileUtility::getFilename($formState
          ->getValue('maxmind_geoip2_bin_db_version'), $formState
          ->getValue('maxmind_geoip2_bin_db_edition'));
        if (!file_exists("{$folder}/{$file}")) {
          $formState
            ->setErrorByName('maxmind_geoip2_bin_db_auto_update', t('Please upload the @file at @path.', [
            '@file' => $file,
            '@path' => $folder,
          ]));
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitFormSettings(AdminSettingsEvent $event) {

    /** @var \Drupal\Core\Form\FormStateInterface $formState */
    $formState = $event
      ->getFormState();
    if ($formState
      ->getValue('smart_ip_data_source') == self::sourceId()) {
      $config = \Drupal::configFactory()
        ->getEditable(self::configName());
      $config
        ->set('version', $formState
        ->getValue('maxmind_geoip2_bin_db_version'))
        ->set('edition', $formState
        ->getValue('maxmind_geoip2_bin_db_edition'))
        ->set('user_account', $formState
        ->getValue('maxmind_geoip2_bin_db_user_account'))
        ->set('license_key', $formState
        ->getValue('maxmind_geoip2_bin_db_license_key'))
        ->set('db_auto_update', $formState
        ->getValue('maxmind_geoip2_bin_db_auto_update'))
        ->set('bin_file_custom_path', $formState
        ->getValue('maxmind_geoip2_bin_db_custom_path'))
        ->save();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function manualUpdate(DatabaseFileEvent $event) {
    $dataSource = \Drupal::config('smart_ip.settings')
      ->get('data_source');
    if ($dataSource == self::sourceId()) {
      DatabaseFileUtility::downloadDatabaseFile();
    }
  }

  /**
   * MaxMind GeoIP2 updates the binary database every Tuesday (both lite and
   * licensed versions), and we download every Wednesday.
   * That means that we only want to download if the current database was
   * downloaded prior to the most recently available version.
   */
  public function cronRun(DatabaseFileEvent $event) {
    $dataSource = \Drupal::config('smart_ip.settings')
      ->get('data_source');
    if ($dataSource == self::sourceId()) {
      $config = \Drupal::config(self::configName());
      $autoUpdate = $config
        ->get('db_auto_update');
      $version = $config
        ->get('version');
      $lastUpdateTime = \Drupal::state()
        ->get('smart_ip_maxmind_geoip2_bin_db.last_update_time') ?: 0;
      $frequency = DatabaseFileUtility::DOWNLOAD_WEEKLY;
      if (DatabaseFileUtility::needsUpdate($lastUpdateTime, $autoUpdate, $frequency)) {
        DatabaseFileUtility::downloadDatabaseFile();
      }
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
SmartIpEventSubscriber::configName public static function Get the config name of this Smart IP data source module. Overrides SmartIpDataSourceInterface::configName
SmartIpEventSubscriber::cronRun public function MaxMind GeoIP2 updates the binary database every Tuesday (both lite and licensed versions), and we download every Wednesday. That means that we only want to download if the current database was downloaded prior to the most recently available version. Overrides SmartIpDataSourceInterface::cronRun
SmartIpEventSubscriber::formSettings public function Add the form elements of this Smart IP data source to main admin settings page of Smart IP. Overrides SmartIpDataSourceInterface::formSettings
SmartIpEventSubscriber::manualUpdate public function Act on manual database update. Overrides SmartIpDataSourceInterface::manualUpdate
SmartIpEventSubscriber::processQuery public function Act on \Drupal\smart_ip\SmartIp::query() when executed and if selected as Smart IP data source, query the IP address against its database. Overrides SmartIpDataSourceInterface::processQuery
SmartIpEventSubscriber::sourceId public static function Smart IP data source module's source ID. Overrides SmartIpDataSourceInterface::sourceId
SmartIpEventSubscriber::submitFormSettings public function Act on submission of main Smart IP admin settings form. Overrides SmartIpDataSourceInterface::submitFormSettings
SmartIpEventSubscriber::validateFormSettings public function Act on validation of main Smart IP admin settings form. Overrides SmartIpDataSourceInterface::validateFormSettings
SmartIpEventSubscriberBase::getSubscribedEvents static function Returns an array of event names this subscriber wants to listen to.
SmartIpEventSubscriberBase::includeEditableConfigNames public function Add Smart IP source module's config name. Overrides SmartIpDataSourceInterface::includeEditableConfigNames