You are here

function smart_ip_admin_settings in Smart IP 6.2

Same name and namespace in other branches
  1. 6 includes/smart_ip.admin.inc \smart_ip_admin_settings()
  2. 7.2 includes/smart_ip.admin.inc \smart_ip_admin_settings()
  3. 7 includes/smart_ip.admin.inc \smart_ip_admin_settings()

Smart IP administration settings.

Return value

Forms for store administrator to set configuration options.

3 string references to 'smart_ip_admin_settings'
device_geolocation_form_alter in modules/device_geolocation/device_geolocation.module
Implements hook_form_alter()
smart_ip_forms in ./smart_ip.module
Implement hook_forms().
smart_ip_menu in ./smart_ip.module
Implements hook_menu().

File

includes/smart_ip.admin.inc, line 14
Admin interface callbacks/handlers to configure Smart IP.

Code

function smart_ip_admin_settings(&$form_state) {
  $smart_ip_source = variable_get('smart_ip_source', 'ipinfodb_service');

  // MaxMind's Apache module mod_geoip, X-GeoIP-Country: XX header and Cloudflare IP Geolocation don't support manual lookup and admin debug
  if ($smart_ip_source == 'mod_geoip' || $smart_ip_source == 'x_header' || $smart_ip_source == 'cf_header') {
    $can_query_ip = FALSE;
  }
  else {
    $can_query_ip = TRUE;
  }
  if ($smart_ip_source == 'local_db') {
    $recover = !variable_get('smart_ip_db_update_busy', FALSE) & (variable_get('smart_ip_get_zip_done', FALSE) | variable_get('smart_ip_extract_zip_done', FALSE) | variable_get('smart_ip_store_location_csv_done', FALSE));

    // Container for database update preference forms
    $form['smart_ip_database_update'] = array(
      '#type' => 'fieldset',
      '#title' => t('Manual database update'),
      '#collapsible' => FALSE,
      '#collapsed' => FALSE,
      '#weight' => 0,
    );
    $update_time = variable_get('smart_ip_last_update', 0);

    // Form for message markup
    $form['smart_ip_database_update']['smart_ip_update_message'] = array(
      '#type' => 'item',
      '#markup' => '<div>' . t('The Smart IP database may be updated manually by pressing the "Update database now" button below. Note, this may take more or less five hours (it depends on the speed of the server). This process can recover from where it stopped or failed.') . '</div>',
      '#suffix' => isset($form_state['storage']['smart_ip_db_message']) ? '<div id="database-update" class="messages">' . $form_state['storage']['smart_ip_db_message'] . '</div>' : '<div id="database-update" class="messages">' . t('Database last updated on ') . format_date($update_time, 'custom', 'n/j/Y') . t(' at ') . format_date($update_time, 'custom', 'H:i:s T') . '</div>',
    );
    $form['smart_ip_database_update']['smart_ip_csv_source'] = array(
      '#type' => 'textfield',
      '#title' => t('CSV URL source'),
      '#default_value' => smart_ip_get_csv_source_filename(),
      '#description' => t("Enter the Maxmind's CSV URL, source for updating the Smart IP database"),
      '#size' => 120,
    );

    // Form for manual updating of the Smart IP database
    $form['smart_ip_database_update']['smart_ip_update_database'] = array(
      '#type' => 'submit',
      '#value' => $recover ? t('Recover database update') : t('Update database now'),
      '#submit' => array(
        '_smart_ip_database_update_submit',
      ),
      '#validate' => array(
        '_smart_ip_database_update_validate',
      ),
      '#suffix' => $recover ? '<div class="messages error">' . t('The previous attempt of updating Smart IP database has failed. Press the button above to continue the unfinished task.') . '</div>' : '',
    );

    // Form to reset (ongoing) update process
    $form['smart_ip_database_update']['smart_ip_reset_update_database'] = array(
      '#type' => 'submit',
      '#value' => t('Reset update process'),
      '#submit' => array(
        '_smart_ip_database_reset_update_submit',
      ),
      '#prefix' => '<div>',
      '#suffix' => '<div class="messages warning">' . t('Caution: The "Reset update process" button above will reset (ongoing) update process and will erase the data stored in database came from maxmind CSV. Please use this function only if the update hanged. It will lead to abnormal update processing if misused.') . '</div></div>',
    );
  }
  if ($smart_ip_source == 'maxmind_bin') {
    if ($smart_ip_source == 'maxmind_bin') {
      $bin_update_error = variable_get('smart_ip_maxmind_bin_db_update_error', FALSE);
      $update_time = variable_get('smart_ip_maxmind_bin_db_last_update', 0);
    }
    elseif ($smart_ip_source == 'maxmindgeoip2_bin') {
      $bin_update_error = variable_get('smart_ip_maxmind_geoip2_bin_db_update_error', FALSE);
      $update_time = variable_get('smart_ip_maxmind_geoip2_bin_db_last_update', 0);
    }
    $last_updated = $update_time ? t('Database last updated on ') . format_date($update_time, 'custom', 'n/j/Y') . t(' at ') . format_date($update_time, 'custom', 'H:i:s T') : t('Database has not been updated');

    // Container for Maxmind bin database update status and manual update
    $form['smart_ip_bin_database_update'] = array(
      '#type' => 'fieldset',
      '#title' => t('Database Update Status'),
      '#collapsible' => FALSE,
      '#collapsed' => FALSE,
      '#weight' => 0,
    );
    $form['smart_ip_bin_database_update']['smart_ip_update_message'] = array(
      '#type' => 'item',
      '#markup' => '<div>' . t('The Maxmind binary database may be updated manually by pressing the "Update database now" button below.') . '</div>',
      '#suffix' => isset($form_state['storage']['smart_ip_bin_db_message']) ? '<div id="bin-database-update" class="messages">' . $form_state['storage']['smart_ip_bin_db_message'] . '</div>' : '<div id="bin-database-update" class="messages">' . $last_updated . '</div>',
    );

    // Form for manual updating of the Smart IP database
    $form['smart_ip_bin_database_update']['smart_ip_bin_update_database'] = array(
      '#type' => 'submit',
      '#value' => t('Update database now'),
      '#submit' => array(
        '_smart_ip_bin_database_update_submit',
      ),
      '#suffix' => $bin_update_error ? '<div class="messages error">' . t('The previous attempt of updating Maxmind binary database has failed with the error: ') . $bin_update_error . '</div>' : '',
    );
  }

  // Container for manual lookup
  $form['smart_ip_manual_lookup'] = array(
    '#type' => 'fieldset',
    '#title' => t('Manual lookup'),
    '#description' => t('Examine database values'),
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
    '#weight' => 1,
    '#access' => $can_query_ip,
  );

  // Form for manual lookups
  $form['smart_ip_manual_lookup']['smart_ip_lookup'] = array(
    '#type' => 'textfield',
    '#title' => t('IP address'),
    '#description' => t('An IP address may be looked up in the database by entering the address above then pressing the %lookup button below.', array(
      '%lookup' => t('Lookup'),
    )),
  );

  // Form for manual manual lookups button
  $form['smart_ip_manual_lookup']['smart_ip_lookup_button'] = array(
    '#type' => 'submit',
    '#value' => t('Lookup'),
    '#submit' => array(
      '_smart_ip_lookup_submit',
    ),
    '#suffix' => isset($form_state['storage']['smart_ip_message']) ? '<div id="lookup-message" class="messages">' . $form_state['storage']['smart_ip_message'] . '</div>' : '',
  );

  // Container for Smart IP source forms
  $form['smart_ip_data_source_selection'] = array(
    '#type' => 'fieldset',
    '#title' => t('Smart IP source'),
    '#description' => t('Please select only one source:'),
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
    '#weight' => 2,
  );

  // Form for Smart IP source selection
  $private_folder = file_directory_path() . '/smart_ip';
  $form['smart_ip_data_source_selection']['smart_ip_source'] = array(
    '#type' => 'radios',
    '#title' => t('Select Smart IP source'),
    '#description' => t('Please populate the appropriate fields below according to your selected Smart IP source.'),
    '#options' => array(
      'abstract_service' => t("Use !abstract web service. You will need a unique API key to use this and you must !register an Abstract account and !login to get and view your !api.", array(
        '!abstract' => l(t('Abstract IP Geolocation'), 'https://www.abstractapi.com/ip-geolocation-api'),
        '!register' => l(t('register'), 'https://app.abstractapi.com/users/signup'),
        '!login' => l(t('logged in'), 'https://app.abstractapi.com/users/login'),
        '!api' => l(t('unique API'), 'https://app.abstractapi.com/api/ip-geolocation/tester'),
      )),
      'ipinfodb_service' => t("Use !ipinfodb web service. The !ip2location free version database is used by !ipinfodb in their web service. You will need an API key to use this and you must be !login to get it. Note: if !ipinfodb respond too slow to geolocation request, your site's performance will be affected specially if Smart IP is configured to geolocate anonymous users.", array(
        '!ipinfodb' => l(t('IPInfoDB.com'), 'http://www.ipinfodb.com'),
        '!ip2location' => l(t('IP2Location'), 'http://ip2location.com'),
        '!login' => l(t('logged in'), 'http://ipinfodb.com/login.php'),
      )),
      'maxmindgeoip_service' => t('Use !maxmind web service. A license key is required here. You will need to !buy one of their services and they will provide you the login details. You can view your license key inside your !account.', array(
        '!maxmind' => l(t('GeoIP Legacy'), 'http://dev.maxmind.com/geoip/legacy/web-services'),
        '!buy' => l(t('buy'), 'https://www.maxmind.com/en/geoip2-precision-services'),
        '!account' => l(t('MaxMind account'), 'https://www.maxmind.com/en/my_license_key'),
      )),
      'maxmindgeoip2_service' => t('Use !maxmind web service. A user ID and license key is required here. You will need to !buy one of their services and they will provide you the login details. You can view your user ID and license key inside your !account.', array(
        '!maxmind' => l(t('MaxMind GeoIP2 Precision'), 'http://dev.maxmind.com/geoip/geoip2/web-services'),
        '!buy' => l(t('buy'), 'https://www.maxmind.com/en/geoip2-precision-services'),
        '!account' => l(t('MaxMind account'), 'https://www.maxmind.com/en/my_license_key'),
      )),
      'ip2location_bin' => t("Use IP2Location binary database. It uses two binary database files; one is for IPV4 address support and the other is for IPV6 address support. You will manually download these two binary database files and upload them to your server. Automatic update is not yet supported here and its your responsibility to update them manually every month. Paid and free versions are available. You need to register first for an account !here for lite version and login !here2 in able to download the two binary database files. For licensed version, you need to buy their product and they will provide you the login details and use it to login !here3. You can download the files !here4 for lite version and !here5 for licensed version. Recommended product ID are DB1 (if you need country level only and more faster query) or DB11 (if you need more details but this is less faster than DB1).", array(
        '!here' => l(t('here'), 'http://lite.ip2location.com/sign-up'),
        '!here2' => l(t('here'), 'http://lite.ip2location.com/login'),
        '!here3' => l(t('here'), 'https://www.ip2location.com/login'),
        '!here4' => l(t('here'), 'http://lite.ip2location.com/database'),
        '!here5' => l(t('here'), 'https://www.ip2location.com/download'),
      )),
      'local_db' => t("Use Smart IP database, the site's local database populated from Maxmind's CSV will be used to query Geo IP information. Note: this option is very expensive to run and it requires about 450MB database and 600MB additional database space for temporary working table."),
      'maxmind_bin' => t("Use MaxMind GeoIP Legacy binary database. Licensed purchased from maxmind.com; you will need to enter your license below. MaxMind GeoIP Legacy's binary database uses \"a custom binary format to maximize lookup speed\", made accessible via their !api. The binary database is roughly 40MB, and will be downloaded and extracted automatically. Lite version binary database can be downloaded !here. The downloaded GeoLiteCity.dat must be uploaded to your server at !path (default) or to your defined custom path.", array(
        '!api' => l(t('custom API'), 'https://github.com/maxmind/geoip-api-php/blob/master/README.md'),
        '!here' => l(t('here'), 'http://dev.maxmind.com/geoip/legacy/geolite'),
        '!path' => $private_folder,
      )),
      'maxmindgeoip2_bin' => t("Use MaxMind GeoIP2 binary database. It is the evolution of MaxMind's original GeoIP binary database or now called GeoIP Legacy. This MaxMind's binary database uses a custom binary format to maximize lookup speed and accessible via two available APIs: !maxmind_db_reader_api which includes an optional C extension that you may install to dramatically increase the performance of lookups in GeoIP2 binary database and the default !geoip2_api. Lite version binary database can be downloaded !here. For licensed version, you will need to enter your license below and the binary database file can be downloaded !here2 (you will need to login to your MaxMind account first). The binary database is roughly 130MB, and there's an option below to enable the automatic download/extraction of it. The downloaded file %file_lite_city (if Lite version City edition) or %file_licensed_city (if Licensed version City edition) or %file_lite_country (if Lite version Country edition) or %file_licensed_country (if Licensed version Country edition) must be uploaded to your server at !path or to your defined custom path.", array(
        '!maxmind_db_reader_api' => l(t('MaxMind DB Reader PHP API'), 'https://github.com/maxmind/MaxMind-DB-Reader-php'),
        '!geoip2_api' => l(t('GeoIP2 PHP API'), 'http://maxmind.github.io/GeoIP2-php'),
        '!here' => l(t('here'), 'https://dev.maxmind.com/geoip/geoip2/geolite2'),
        '!here2' => l(t('here'), 'https://www.maxmind.com/en/download_files'),
        '%file_lite_city' => SMART_IP_MAXMIND_GEOIP2_FILENAME_LITE_CITY,
        '%file_licensed_city' => SMART_IP_MAXMIND_GEOIP2_FILENAME_LINCENSED_CITY,
        '%file_lite_country' => SMART_IP_MAXMIND_GEOIP2_FILENAME_LITE_COUNTRY,
        '%file_licensed_country' => SMART_IP_MAXMIND_GEOIP2_FILENAME_LINCENSED_COUNTRY,
        '!path' => $private_folder,
      )),
      'mod_geoip' => t("Use MaxMind's Apache module mod_geoip... !read_more.", array(
        '!read_more' => l(t('read more'), 'http://dev.maxmind.com/geoip/legacy/mod_geoip2'),
      )),
      'x_header' => t('Use the X-GeoIP-Country: XX header, set by e.g. nginx'),
      'es_header' => t('Use Akamai EdgeScape: your website must be using Akamai CDN and "EdgeScape Geolocation" option must be enabled at your !settings.', array(
        '!settings' => l(t('Akamai settings'), 'https://control.akamai.com/apps/auth'),
      )),
      'cf_header' => t('Use Cloudflare IP Geolocation: your website must be using Cloudflare CDN and "IP Geolocation" option must be enabled at your !settings.', array(
        '!settings' => l(t('Cloudflare settings'), 'https://www.cloudflare.com/cloudflare-settings'),
      )),
    ),
    '#default_value' => variable_get('smart_ip_source', 'ipinfodb_service'),
  );

  // Form to select Abstract IP Geolocation web service version
  $form['smart_ip_data_source_selection']['smart_ip_abstract_version'] = array(
    '#type' => 'select',
    '#title' => t('Abstract IP Geolocation web service version'),
    '#default_value' => variable_get('smart_ip_abstract_version', 1),
    '#options' => array(
      1 => 1,
    ),
    '#description' => t('Select an Abstract IP Geolocation web service version.'),
    '#states' => array(
      'visible' => array(
        ':input[name="smart_ip_source"]' => array(
          'value' => 'abstract_service',
        ),
      ),
    ),
  );

  // Form for entering Abstract IP Geolocation web service API key
  $form['smart_ip_data_source_selection']['smart_ip_abstract_key'] = array(
    '#type' => 'textfield',
    '#title' => t('Abstract IP Geolocation web service API key'),
    '#description' => t('The use of Abstract IP Geolocation web service requires API key. Registration for the new API key is free, sign up !here.', array(
      '!here' => l(t('here'), 'https://app.abstractapi.com/users/signup'),
    )),
    '#default_value' => variable_get('smart_ip_abstract_key', ''),
    '#states' => array(
      'visible' => array(
        ':input[name="smart_ip_source"]' => array(
          'value' => 'abstract_service',
        ),
      ),
    ),
  );

  // Form to select IPInfoDB API version
  $form['smart_ip_data_source_selection']['smart_ip_use_ipinfodb_api_version'] = array(
    '#type' => 'select',
    '#title' => t('IPInfoDB API version'),
    '#default_value' => variable_get('smart_ip_use_ipinfodb_api_version', 3),
    '#options' => array(
      2 => 2,
      3 => 3,
    ),
    '#description' => t('IPInfoDB.com version 2 do have region code, in version 3 it was removed.'),
  );

  // Form for entering IPInfoDB API key
  $form['smart_ip_data_source_selection']['smart_ip_ipinfodb_key'] = array(
    '#type' => 'textfield',
    '#title' => t('IPInfoDB API key'),
    '#description' => t('The use of IPInfoDB.com service requires API key. Registration for the new API key is free, sign up !here.', array(
      '!here' => l(t('here'), 'http://www.ipinfodb.com/register.php'),
    )),
    '#default_value' => variable_get('smart_ip_ipinfodb_key', ''),
  );

  // Form for choosing MaxMind GeoIP Legacy Web Services
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_service'] = array(
    '#type' => 'select',
    '#title' => t('MaxMind GeoIP Legacy Web Services'),
    '#description' => t('Choose type of service.'),
    '#options' => array(
      'country' => t('Country'),
      'city' => t('City'),
      'city_isp_org' => t('City/ISP/Organization'),
      'omni' => t('Insights (formerly Omni)'),
    ),
    '#default_value' => variable_get('smart_ip_maxmind_service', 'country'),
  );

  // Form for entering MaxMind GeoIP Legacy Web Services developer key
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_key'] = array(
    '#type' => 'textfield',
    '#title' => t('MaxMind GeoIP Legacy Web Services developer key'),
    '#description' => t('The use of geoip.maxmind.com service requires developer key.'),
    '#default_value' => variable_get('smart_ip_maxmind_key', ''),
  );

  // Form for choosing MaxMind GeoIP2 Precision Web Services
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_geoip_service'] = array(
    '#type' => 'select',
    '#title' => t('MaxMind GeoIP2 Precision Web Services'),
    '#description' => t('Choose type of service.'),
    '#options' => array(
      'country' => t('Country'),
      'city' => t('City'),
      'insights' => t('Insights'),
    ),
    '#default_value' => variable_get('smart_ip_maxmind_geoip_service', 'country'),
  );

  // Form for MaxMind GeoIP2 Precision user ID
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_geoip_uid'] = array(
    '#type' => 'textfield',
    '#title' => t('MaxMind GeoIP2 Precision user ID'),
    '#description' => t("Enter your MaxMind GeoIP2 Precision account's user ID (view your user ID !here).", array(
      '!here' => l(t('here'), 'https://www.maxmind.com/en/my_license_key'),
    )),
    '#default_value' => variable_get('smart_ip_maxmind_geoip_uid', ''),
    '#size' => 30,
  );

  // Form for MaxMind GeoIP2 Precision license key
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_geoip_license'] = array(
    '#type' => 'textfield',
    '#title' => t('MaxMind GeoIP2 Precision license key'),
    '#default_value' => variable_get('smart_ip_maxmind_geoip_license', ''),
    '#description' => t("Enter your MaxMind GeoIP2 Precision account's license key (view your license key !here).", array(
      '!here' => l(t('here'), 'https://www.maxmind.com/en/my_license_key'),
    )),
    '#size' => 30,
  );

  // Form for choosing IP2Location cache
  $form['smart_ip_data_source_selection']['smart_ip_ip2location_bin_cache'] = array(
    '#type' => 'select',
    '#title' => t('IP2Location caching method'),
    '#description' => t('"No cache" - standard lookup with no cache and directly reads from the database file. "Memory cache" - cache the database into memory to accelerate lookup speed and read the whole database into a variable for caching. "Shared memory" - cache whole database into system memory and share among other scripts and websites. Please make sure your system have sufficient RAM if enabling "Memory cache" or "Shared memory".'),
    '#options' => array(
      'no_cache' => t('No cache'),
      'memory_cache' => t('Memory cache'),
      'shared_memory' => t('Shared memory'),
    ),
    '#default_value' => variable_get('smart_ip_ip2location_bin_cache', 'no_cache'),
  );

  // Form for entering IP2Location IPV4 binary database file path
  $form['smart_ip_data_source_selection']['smart_ip_ip2location_bin_path'] = array(
    '#type' => 'textfield',
    '#title' => t('IP2Location binary database IPV4 file full path'),
    '#description' => t('Define the full path where the IP2Location IPV4 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 the filename. Eg. /var/www/sites/default/private/smart_ip/IP2LOCATION-LITE-DB11.BIN', array(
      '!security' => l(t('more information about securing private files'), 'https://www.drupal.org/documentation/modules/upload'),
    )),
    '#default_value' => variable_get('smart_ip_ip2location_bin_path', ''),
  );

  // Form for entering IP2Location IPV6 binary database file path
  $form['smart_ip_data_source_selection']['smart_ip_ip2location_ipv6_bin_path'] = array(
    '#type' => 'textfield',
    '#title' => t('IP2Location binary database IPV6 file full path'),
    '#description' => t('Define the full path where the IP2Location IPV6 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 the filename. Eg. /var/www/sites/default/private/smart_ip/IP2LOCATION-LITE-DB11.IPV6.BIN', array(
      '!security' => l(t('more information about securing private files'), 'https://www.drupal.org/documentation/modules/upload'),
    )),
    '#default_value' => variable_get('smart_ip_ip2location_ipv6_bin_path', ''),
  );

  // Form selection for MaxMind GeoIP Legacy binary database lite or paid version
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_bin_version'] = array(
    '#type' => 'select',
    '#title' => t('MaxMind GeoIP Legacy binary database version'),
    '#description' => t('Select version of MaxMind GeoIP Legacy binary database.'),
    '#options' => array(
      SMART_IP_MAXMIND_BIN_LICENSED_VERSION => t('Licensed'),
      SMART_IP_MAXMIND_BIN_LITE_VERSION => t('Lite'),
    ),
    '#default_value' => variable_get('smart_ip_maxmind_bin_version', SMART_IP_MAXMIND_BIN_LICENSED_VERSION),
  );

  // Form selection for MaxMind GeoIP Legacy binary database edition
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_bin_edition'] = array(
    '#type' => 'select',
    '#title' => t('MaxMind GeoIP Legacy binary database edition'),
    '#description' => t('Select edition of MaxMind GeoIP Legacy binary database.'),
    '#options' => array(
      SMART_IP_MAXMIND_BIN_EDITION_CITY => t('City'),
      SMART_IP_MAXMIND_BIN_EDITION_COUNTRY => t('Country'),
    ),
    '#default_value' => variable_get('smart_ip_maxmind_bin_edition', SMART_IP_MAXMIND_BIN_EDITION_CITY),
  );

  // Form for MaxMind GeoIP Legacy binary database license key
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_license'] = array(
    '#type' => 'textfield',
    '#title' => t('MaxMind GeoIP Legacy license key'),
    '#default_value' => variable_get('smart_ip_maxmind_license', ''),
    '#description' => t("Enter your MaxMind GeoIP Legacy account's license key (view your license key !here). This is required for licensed version.", array(
      '!here' => l(t('here'), 'https://www.maxmind.com/en/my_license_key'),
    )),
    '#size' => 30,
  );

  // Form to enable automatic MaxMind GeoIP Legacy binary database update every week
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_bin_db_auto_update'] = array(
    '#type' => 'select',
    '#title' => t('Automatic MaxMind GeoIP Legacy binary database update'),
    '#description' => t('MaxMind GeoIP Legacy binary database will be automatically updated via cron.php every Wednesday (for licensed version) and every first Wednesday of the month (for lite or free version). MaxMind GeoIP Legacy updates their database every Tuesday for licensed version and every first Tuesday of the month for lite or free version. Cron must be enabled for this to work (!read).', array(
      '!read' => l(t('configuring cron jobs'), 'https://drupal.org/cron'),
    )),
    '#options' => array(
      TRUE => t('Yes'),
      FALSE => t('No'),
    ),
    '#default_value' => variable_get('smart_ip_maxmind_bin_db_auto_update', TRUE),
  );

  // Form for entering MaxMind GeoIP Legacy binary database custom path
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_bin_custom_path'] = array(
    '#type' => 'textfield',
    '#title' => t('MaxMind GeoIP Legacy binary database custom path'),
    '#description' => t('Define the path where the MaxMind GeoIP Legacy 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 GeoIP Legacy binary database and it can be also useful for server with installed GeoIPLookup CLI tool where its MaxMind GeoIP Legacy binary database file can be used here (usually its path is located at /usr/share/GeoIP). This path will be ignored if "Automatic MaxMind GeoIP Legacy 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.', array(
      '!security' => l(t('more information about securing private files'), 'https://www.drupal.org/documentation/modules/upload'),
    )),
    '#default_value' => variable_get('smart_ip_maxmind_bin_custom_path', ''),
  );

  // Form selection for MaxMind GeoIP2 binary database lite or paid version
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_geoip2_bin_version'] = array(
    '#type' => 'select',
    '#title' => t('MaxMind GeoIP2 binary database version'),
    '#description' => t('Select version of MaxMind GeoIP2 binary database.'),
    '#options' => array(
      SMART_IP_MAXMIND_BIN_LICENSED_VERSION => t('Licensed'),
      SMART_IP_MAXMIND_BIN_LITE_VERSION => t('Lite'),
    ),
    '#default_value' => variable_get('smart_ip_maxmind_geoip2_bin_version', SMART_IP_MAXMIND_BIN_LICENSED_VERSION),
  );

  // Form selection for MaxMind GeoIP2 binary database edition
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_geoip2_bin_edition'] = array(
    '#type' => 'select',
    '#title' => t('MaxMind GeoIP2 binary database edition'),
    '#description' => t('Select edition of MaxMind GeoIP2 binary database.'),
    '#options' => array(
      SMART_IP_MAXMIND_GEOIP2_BIN_EDITION_CITY => t('City'),
      SMART_IP_MAXMIND_GEOIP2_BIN_EDITION_COUNTRY => t('Country'),
    ),
    '#default_value' => variable_get('smart_ip_maxmind_geoip2_bin_edition', SMART_IP_MAXMIND_GEOIP2_BIN_EDITION_CITY),
  );

  // Form for MaxMind GeoIP2 binary database user account
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_geoip2_bin_user_account'] = array(
    '#type' => 'textfield',
    '#title' => t('MaxMind user account'),
    '#default_value' => variable_get('smart_ip_maxmind_geoip2_bin_user_account', ''),
    '#description' => t('Enter your MaxMind user account. This is required for lite version.'),
    '#size' => 30,
  );

  // Form for MaxMind GeoIP2 binary database license key
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_geoip2_license'] = array(
    '#type' => 'textfield',
    '#title' => t('MaxMind GeoIP2 license key'),
    '#default_value' => variable_get('smart_ip_maxmind_geoip2_license', ''),
    '#description' => t("Enter your MaxMind GeoIP2 account's license key (view your license key !here). This is required for both lite and licensed version.", array(
      '!here' => l(t('here'), 'https://www.maxmind.com/en/my_license_key'),
    )),
    '#size' => 30,
  );

  // Form to enable automatic MaxMind GeoIP2 binary database update every week
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_geoip2_bin_db_auto_update'] = array(
    '#type' => 'select',
    '#title' => t('Automatic MaxMind GeoIP2 binary database update'),
    '#description' => t('MaxMind GeoIP2 binary database will be automatically updated via cron.php every Wednesday (for licensed version) and every first Wednesday of the month (for lite or free version). MaxMind GeoIP2 updates their database every Tuesday for licensed version and every first Tuesday of the month for lite or free version. Cron must be enabled for this to work (!read).', array(
      '!read' => l(t('configuring cron jobs'), 'https://drupal.org/cron'),
    )),
    '#options' => array(
      TRUE => t('Yes'),
      FALSE => t('No'),
    ),
    '#default_value' => variable_get('smart_ip_maxmind_geoip2_bin_db_auto_update', TRUE),
  );

  // Form for entering MaxMind GeoIP2 binary database custom path
  $form['smart_ip_data_source_selection']['smart_ip_maxmind_geoip2_bin_custom_path'] = array(
    '#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 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.', array(
      '!security' => l(t('more information about securing private files'), 'https://www.drupal.org/documentation/modules/upload'),
    )),
    '#default_value' => variable_get('smart_ip_maxmind_geoip2_bin_custom_path', ''),
  );

  // Form to enable automatic Smart IP database update every one month
  $form['smart_ip_data_source_selection']['smart_ip_auto_update'] = array(
    '#type' => 'select',
    '#title' => t('Automatic Smart IP database update'),
    '#description' => t('Database will be automatically updated via cron.php every one month (Maxmind updates every first day of a month). Cron must be enabled for this to work (!read).', array(
      '!read' => l(t('configuring cron jobs'), 'https://drupal.org/cron'),
    )),
    '#options' => array(
      TRUE => t('Yes'),
      FALSE => t('No'),
    ),
    '#default_value' => variable_get('smart_ip_auto_update', TRUE),
  );

  // Container for preference forms
  $form['smart_ip_preferences'] = array(
    '#type' => 'fieldset',
    '#title' => t('Smart IP settings'),
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
    '#weight' => 3,
  );

  // Form to select Request Timeout
  $form['smart_ip_preferences']['smart_ip_get_location_timeout'] = array(
    '#type' => 'select',
    '#title' => t('Request Timeout'),
    '#description' => t('This timeout (in seconds) will be set for all requests to external IP location services via drupal_http_request()'),
    '#options' => drupal_map_assoc(array(
      1,
      2,
      5,
      10,
      20,
      30,
    )),
    '#default_value' => variable_get('smart_ip_get_location_timeout', 2),
  );

  // Form to select user roles to geolocate
  drupal_add_js(drupal_get_path('module', 'smart_ip') . '/js/smart_ip-admin.js');
  $roles = user_roles();
  $form['smart_ip_preferences']['smart_ip_roles_to_geolocate'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Roles To Geolocate'),
    '#default_value' => variable_get('smart_ip_roles_to_geolocate', array(
      DRUPAL_AUTHENTICATED_RID,
    )),
    '#options' => $roles,
    '#description' => t('Select the roles you wish to geolocate. Note that selecting the anonymous role will add substantial overhead.'),
  );
  $eu_visitor_dont_save = t("Don't save location details of visitors from GDPR countries");
  $form['smart_ip_preferences']['smart_ip_eu_visitor_dont_save'] = array(
    '#type' => 'checkbox',
    '#title' => $eu_visitor_dont_save,
    '#default_value' => variable_get('smart_ip_eu_visitor_dont_save', FALSE),
    '#description' => t("If a visitor's country is an GDPR country, its location details will not be saved."),
  );
  $geotimezone_exists = module_exists('geotimezone');
  if (!$geotimezone_exists) {
    $tz_format_desc = t('Please install and enable !module.', array(
      '!module' => l(t('Geo Time Zone'), 'https://www.drupal.org/project/geotimezone'),
    ));
  }
  else {
    $tz_format_desc = t('Select the format of the time zone field.');
  }
  $form['smart_ip_preferences']['smart_ip_timezone_format'] = array(
    '#type' => 'select',
    '#disabled' => !$geotimezone_exists,
    '#title' => t('Time zone format'),
    '#description' => $tz_format_desc,
    '#default_value' => variable_get('smart_ip_timezone_format', 'identifier'),
    '#options' => array(
      'identifier' => t('Identifier (E.g Asia/Manila)'),
      'offset' => t('UTC/GMT Offset (E.g +08:00)'),
    ),
  );
  $form['smart_ip_preferences']['smart_ip_allowed_pages'] = array(
    '#title' => t("Acquire/update user's geolocation on specific Drupal native pages"),
    '#type' => 'textarea',
    '#rows' => 5,
    '#description' => t("Specify pages by using their paths (not the aliased path). Enter one path per line. The '*' character is a wildcard. Example paths are blog for the blog page and blog/* for every personal blog. &lt;front&gt; is the front page. Leave blank if all pages."),
    '#default_value' => implode("\n", variable_get('smart_ip_allowed_pages', array())),
  );

  // Container for Smart IP debug tool
  $form['smart_ip_debug_tool'] = array(
    '#type' => 'fieldset',
    '#title' => t('Smart IP debug tool'),
    '#description' => t('Note: Make sure that the debug role is also enabled in "Roles to
        Geolocate" under "Smart IP settings" above. If a user has multiple
        roles, the precedence of what debug IP address of a role will be used is
        determined in alphabetical order but the "authenticated role will always
        be the last priority. Eg. if a user has "authenticated", "editor" and
        "moderator" roles, (assuming all debug roles are enabled) the debug IP
        address that will be used is the "editor" role.'),
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
    '#weight' => 5,
    '#access' => $can_query_ip,
  );
  $roles_debug = variable_get('smart_ip_roles_in_debug_mode', array());
  $roles_debug_ip = variable_get('smart_ip_roles_in_debug_mode_ip', array());
  foreach ($roles as $role_id => $role) {

    // Form to turn on debugging
    $form['smart_ip_debug_tool']["smart_ip_debug_{$role_id}"] = array(
      '#type' => 'checkbox',
      '#title' => t('@role role in debug mode', array(
        '@role' => $role,
      )),
      '#default_value' => isset($roles_debug[$role_id]) && $roles_debug[$role_id] ? TRUE : FALSE,
      '#description' => t('Enables @role role to spoof an IP Address for debugging purposes.', array(
        '@role' => $role,
      )),
    );
    $form['smart_ip_debug_tool']["smart_ip_test_ip_address_{$role_id}"] = array(
      '#type' => 'textfield',
      '#title' => t('IP address to use for @role role testing', array(
        '@role' => $role,
      )),
      '#default_value' => isset($roles_debug_ip[$role_id]) ? $roles_debug_ip[$role_id] : NULL,
    );
  }
  $form = system_settings_form($form);
  $form['buttons']['#weight'] = 100;

  // Define submit handler function
  $form['#submit'][] = 'smart_ip_admin_settings_submit';
  $form['#validate'][] = 'smart_ip_admin_settings_validate';
  return $form;
}