You are here

wunderground_weather.module in Wunderground weather 7

Same filename and directory in other branches
  1. 8 wunderground_weather.module

Wunderground weather module to display weather forecasts and current weather conditions in blocks.

File

wunderground_weather.module
View source
<?php

/**
 * @file
 * Wunderground weather module to display weather forecasts and current
 * weather conditions in blocks.
 */

/**
 * Implements hook_help().
 */
function wunderground_weather_help($path, $arg) {
  switch ($path) {

    // Main module help for this module.
    case 'admin/help#wunderground_weather':
      return '<p>' . t('The Wunderground weather module provides two types of blocks, one with current weather conditions and one with weatherforecasts for a certain location. You can choose how many blocks of each kind you want. The weather data is retrieved by making calls to the Wunderground API. In order to use this module, you will need to create an API at @url. You can either choose for a free account or you can sign up for a paid account, in which case you will be allowed to make lot more requests per day. Once you have obtained your API key, you can go to the Wunderground weather settings page and fill in the key. Here you should also enter the language you would like to use and choose to use caching or not. Caching will reduce the number of calls to Wunderground and is a lot faster. If you choose not to cache, you will have the most up to date data in your blocks. When you have completed the settings form, you can place your block on the page. You can configure each block by choosing a location and the data you want to display.', array(
        '@url' => url('http://www.wunderground.com/weather/api'),
      )) . '</p>';
  }
}

/**
 * Implements hook_permission().
 */
function wunderground_weather_permission() {
  return array(
    'administer wunderground weather' => array(
      'title' => t('Administer Wunderground Weather'),
      'description' => t('Perform administration tasks for the Wunderground Weather module.'),
    ),
  );
}

/**
 * Implements hook_variable_info().
 */
function wunderground_weather_variable_info($options) {
  $variables['wunderground_weather_language'] = array(
    'type' => 'select',
    'title' => t('Wunderground weather Language', array(), $options),
    'default' => 'EN',
    'options' => _wunderground_weather_languages(),
    'description' => t('The language of the displayed weather data.', array(), $options),
    'localize' => TRUE,
  );
  $variables['wunderground_weather_degrees'] = array(
    'type' => 'select',
    'title' => t('Wunderground weather Degrees unit', array(), $options),
    'default' => 'celsius',
    'options' => array(
      'fahrenheit' => t('Fahrenheit', array(), $options),
      'celsius' => t('Celsius', array(), $options),
    ),
    'description' => t('The unit of temperature.', array(), $options),
    'localize' => TRUE,
  );
  $variables['wunderground_weather_distance'] = array(
    'type' => 'select',
    'title' => t('Wunderground weather Distance unit', array(), $options),
    'default' => 'km',
    'options' => array(
      'mi' => t('Miles', array(), $options),
      'km' => t('Kilometers', array(), $options),
    ),
    'description' => t('The unit of distance.', array(), $options),
    'localize' => TRUE,
  );
  return $variables;
}

/**
 * Implements hook_menu().
 */
function wunderground_weather_menu() {

  // Admin page.
  $items['admin/config/services/wunderground-weather'] = array(
    'title' => 'Wunderground weather settings',
    'description' => 'Perform administration tasks for Wunderground weather.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'wunderground_weather_admin_form',
    ),
    'access arguments' => array(
      'administer wunderground weather',
    ),
    'file' => '/wunderground_weather.admin.inc',
  );

  // Menu item for getting location by autocomplete.
  $items['wunderground-locations'] = array(
    'type' => MENU_CALLBACK,
    'page callback' => 'wunderground_weather_location_autocomplete',
    'access arguments' => array(
      'access content',
    ),
  );
  return $items;
}

/**
 * Implements hook_theme().
 */
function wunderground_weather_theme() {
  return array(
    'wunderground_weather_forecast' => array(
      'variables' => array(
        'simpleforecast' => NULL,
      ),
    ),
    'wunderground_weather_current' => array(
      'variables' => array(
        'image' => NULL,
        'summary' => NULL,
      ),
      'template' => 'templates/wunderground_weather_current',
    ),
    'wunderground_weather_field_drag' => array(
      'render element' => 'form',
    ),
  );
}

/**
 * Theme function to create draggable fields.
 */
function theme_wunderground_weather_field_drag($variables) {
  $form = $variables['form'];

  // Initialize the variable which will store table rows.
  $rows = array();

  // Iterate over each element in $form['fields'] array.
  foreach (element_children($form['fields'], TRUE) as $id) {
    $form['fields'][$id]['weight']['#attributes']['class'] = array(
      'field-item-weight',
    );
    $rows[] = array(
      'data' => array(
        drupal_render($form['fields'][$id]['name']),
        drupal_render($form['fields'][$id]['enabled']),
        drupal_render($form['fields'][$id]['weight']),
      ),
      'class' => array(
        'draggable',
      ),
    );
  }
  $header = array(
    t('Field'),
    t('Enabled'),
    t('Weight'),
  );
  $table_id = 'field-items-table';
  $output = theme('table', array(
    'header' => $header,
    'rows' => $rows,
    'attributes' => array(
      'id' => $table_id,
    ),
  ));
  drupal_add_tabledrag($table_id, 'order', 'sibling', 'field-item-weight');
  return $output;
}

/**
 * Implements hook_block_info().
 */
function wunderground_weather_block_info() {
  for ($f = 1; $f <= variable_get('wunderground_weather_block_forecast_amount', '1'); $f++) {
    $blocks['wunderground_weather_forecast_' . $f] = array(
      'info' => t('Wunderground Weather Forecast !amount', array(
        '!amount' => $f,
      )),
      'cache' => DRUPAL_NO_CACHE,
    );
  }
  for ($t = 1; $t <= variable_get('wunderground_weather_block_current_amount', '1'); $t++) {
    $blocks['wunderground_weather_current_' . $t] = array(
      'info' => t('Wunderground Current Weather !amount', array(
        '!amount' => $t,
      )),
      'cache' => DRUPAL_NO_CACHE,
    );
  }
  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function wunderground_weather_block_view($delta) {
  $block = array();
  for ($f = 1; $f <= variable_get('wunderground_weather_block_forecast_amount', '1'); $f++) {
    if ($delta == 'wunderground_weather_forecast_' . $f) {
      $block['subject'] = t('Weather forecast !amount', array(
        '!amount' => $f,
      ));
      $block['content'] = wunderground_weather_get_forecast($f);
    }
  }
  for ($t = 1; $t <= variable_get('wunderground_weather_block_current_amount', '1'); $t++) {
    if ($delta == 'wunderground_weather_current_' . $t) {
      $block['subject'] = t('Current weather !amount', array(
        '!amount' => $t,
      ));
      $block['content'] = wunderground_weather_get_current($t);
    }
  }
  return $block;
}

/**
 * Implements hook_block_configure().
 */
function wunderground_weather_block_configure($delta = '') {
  $form['draggable']['#theme'] = 'wunderground_weather_field_drag';
  $form['draggable']['fields']['#tree'] = TRUE;

  // Configuration for forecast blocks.
  for ($f = 1; $f <= variable_get('wunderground_weather_block_forecast_amount', '1'); $f++) {
    if ($delta == 'wunderground_weather_forecast_' . $f) {
      wunderground_weather_block_configure_location_fields($form, 'forecast', $f);
      $date_formats = array();
      $date_types = system_get_date_types();
      foreach ($date_types as $key => $value) {
        $date_formats[$value['type']] = t('@date_format format', array(
          '@date_format' => $value['title'],
        )) . ': ' . format_date(REQUEST_TIME, $value['type']);
      }
      $form['date'] = array(
        '#type' => 'fieldset',
        '#title' => t('Dates'),
        '#description' => t('Choose a date format'),
      );
      $form['date']['wunderground_weather_forecast_date_format_' . $f] = array(
        '#type' => 'select',
        '#title' => t('Date format'),
        '#options' => $date_formats,
        '#default_value' => variable_get('wunderground_weather_forecast_date_format_' . $f, 'medium'),
      );
      $serialized_fields = variable_get($delta . '_fields', FALSE);
      $block_fields = $serialized_fields ? unserialize($serialized_fields) : wunderground_weather_forecast_fields();
      $i = 0;
      foreach (wunderground_weather_forecast_fields() as $key => $value) {
        $form['draggable']['fields'][$key] = array(
          'name' => array(
            '#markup' => check_plain($value),
          ),
          'enabled' => array(
            '#type' => 'checkbox',
            '#default_value' => isset($block_fields[$key]['#enabled']) ? $block_fields[$key]['#enabled'] : TRUE,
          ),
          'weight' => array(
            '#type' => 'weight',
            '#title' => t('Weight'),
            '#default_value' => isset($block_fields[$key]['#weight']) ? $block_fields[$key]['#weight'] : $i,
            '#delta' => 6,
            '#title_display' => 'invisible',
          ),
          '#weight' => isset($block_fields[$key]['#weight']) ? $block_fields[$key]['#weight'] : $i,
        );
        ++$i;
      }
      $form['icons'] = array(
        '#type' => 'fieldset',
        '#title' => t('Icons'),
      );
      $alphas = range('a', 'k');
      foreach ($alphas as $letter) {
        $icon_options[$letter] = _wunderground_weather_get_icons_sample($letter);
      }
      $form['icons']['wunderground_weather_forecast_icons_' . $f] = array(
        '#type' => 'radios',
        '#title' => t('Select the icon set you want to use.'),
        '#options' => $icon_options,
        '#default_value' => variable_get('wunderground_weather_forecast_icons_' . $f, 'a'),
      );
    }
  }

  // Configuration for current weather condition blocks.
  for ($t = 1; $t <= variable_get('wunderground_weather_block_current_amount', '1'); $t++) {
    if ($delta == 'wunderground_weather_current_' . $t) {
      wunderground_weather_block_configure_location_fields($form, 'current', $t);
      $serialized_fields = variable_get($delta . '_fields', FALSE);
      $block_fields = $serialized_fields ? unserialize($serialized_fields) : wunderground_weather_current_fields();
      $i = 0;
      foreach (wunderground_weather_current_fields() as $key => $value) {
        $form['draggable']['fields'][$key] = array(
          'name' => array(
            '#markup' => check_plain($value),
          ),
          'enabled' => array(
            '#type' => 'checkbox',
            '#default_value' => isset($block_fields[$key]['#enabled']) ? $block_fields[$key]['#enabled'] : TRUE,
          ),
          'weight' => array(
            '#type' => 'weight',
            '#title' => t('Weight'),
            '#default_value' => isset($block_fields[$key]['#weight']) ? $block_fields[$key]['#weight'] : $i,
            '#delta' => 6,
            '#title_display' => 'invisible',
          ),
          '#weight' => isset($block_fields[$key]['#weight']) ? $block_fields[$key]['#weight'] : $i,
        );
        ++$i;
      }
      $form['icons'] = array(
        '#type' => 'fieldset',
        '#title' => t('Icons'),
      );
      $alphas = range('a', 'k');
      foreach ($alphas as $letter) {
        $icon_options[$letter] = _wunderground_weather_get_icons_sample($letter);
      }
      $form['icons']['wunderground_weather_current_icons_' . $t] = array(
        '#type' => 'radios',
        '#title' => t('Select the icon set you want to use.'),
        '#options' => $icon_options,
        '#default_value' => variable_get('wunderground_weather_current_icons_' . $t, 'a'),
      );
    }
  }
  return $form;
}

/**
 * Attach location fields to the block configure forms.
 *
 * @param array $form
 *   The form array.
 *
 * @param string $type
 *   Kind of block to make fields for.
 *
 * @param int $block_number
 *   Number of the block to add fields to.
 *
 * @return array
 *   Form fields to select a location.
 */
function wunderground_weather_block_configure_location_fields(&$form, $type, $block_number) {
  $form['location'] = array(
    '#type' => 'fieldset',
    '#title' => t('Location'),
  );

  // Autocomplete to get location.
  $form['location']['wunderground_weather_location_' . $type . '_' . $block_number] = array(
    '#title' => t('Location path'),
    '#type' => 'textfield',
    '#description' => t('Search for your city to determine the Wunderground location path.'),
    '#maxlength' => 120,
    '#required' => TRUE,
    '#autocomplete_path' => 'wunderground-locations',
    '#default_value' => variable_get('wunderground_weather_location_' . $type . '_' . $block_number, ''),
  );
  return $form;
}

/**
 * Implements hook_block_save().
 */
function wunderground_weather_block_save($delta = '', $edit = array()) {

  // Save wunderground_weather settings.
  foreach ($edit as $key => $value) {
    if (substr($key, 0, 20) === 'wunderground_weather') {
      variable_set($key, $value);
    }
  }
  $block_fields = array();
  foreach ($edit['fields'] as $key => $field) {
    $block_fields[$key] = array(
      '#enabled' => check_plain($field['enabled']),
      '#weight' => check_plain($field['weight']),
    );
    variable_set($delta . '_fields', serialize($block_fields));
  }

  // @todo Clear specific cache entries.
  cache_clear_all('*', 'cache', TRUE);
}

/**
 * Get forecast data and return a themed table.
 *
 * @return string
 *   Html for the forecast block.
 */
function wunderground_weather_get_forecast($block_number) {
  $variables = _wunderground_weather_cache('forecast', $block_number);

  // Check if data is received.
  if ($variables['days']) {
    $output = theme('wunderground_weather_forecast', $variables);
  }
  else {

    // Return message if no data is retrieved.
    $output = t('No weather forecast available.');
    if (user_access('administer wunderground weather')) {
      $configure_path = 'admin/structure/block/manage/wunderground_weather/wunderground_weather_forecast_' . $block_number . '/configure';
      $output .= ' ' . l(t('Configure this block'), $configure_path);
    }
  }
  return $output;
}

/**
 * Get weather forecast from Wunderground.
 */
function wunderground_weather_get_forecast_data($block_number = '') {
  $location = variable_get('wunderground_weather_location_forecast_' . $block_number, FALSE);
  if ($location) {
    preg_match('#\\[(.*?)\\]#', variable_get('wunderground_weather_location_forecast_' . $block_number, ''), $match);
    $path = $match[1];
    $options = array(
      'key' => variable_get('wunderground_weather_api_key', ''),
      'data_feature' => 'forecast',
      'language' => 'lang:' . strtoupper(variable_get('wunderground_weather_language', 'EN')),
      'path' => $path,
    );
    $response = wunderground_weather_http_request($options, $path);
    $serialized_fields = variable_get('wunderground_weather_forecast_' . $block_number . '_fields');
    $data['fields'] = unserialize($serialized_fields);
    if ($response) {
      $data['days'] = $response['forecast']['simpleforecast']['forecastday'];

      // Set url for icons sets.
      foreach ($data['days'] as $nr => $day) {
        $icon = $data['days'][$nr]['icon'];
        $icon_set = variable_get('wunderground_weather_forecast_icons_' . $block_number);
        $data['days'][$nr]['icon_url'] = _wunderground_weather_get_icon_url($icon, $icon_set);
      }
    }
    else {
      $data['days'] = FALSE;
    }
  }
  else {
    $data['days'] = FALSE;
  }
  return $data;
}

/**
 * Theme function to render weather forecast block.
 */
function theme_wunderground_weather_forecast($variables) {
  $header = array();
  $rows = array();
  $degrees = variable_get('wunderground_weather_degrees', 'celsius');
  foreach ($variables['days'] as $day) {
    if (!empty($day)) {

      // Format date.
      $date_format = variable_get('wunderground_weather_forecast_date_format_' . $variables['block_number'], 'medium');
      $date = format_date($day['date']['epoch'], $date_format);

      // Table header.
      $header[] = array(
        'data' => $date,
      );

      // Build rows.
      foreach (element_children($variables['fields'], TRUE) as $field) {
        if ($variables['fields'][$field]['#enabled'] == 1) {
          switch ($field) {
            case 'image':
              $rows[$field][] = theme('image', array(
                'path' => $day['icon_url'],
                'alt' => t('Weather forecast for !date', array(
                  '!date' => $date,
                )),
                'title' => t('Weather forecast for !date', array(
                  '!date' => $date,
                )),
                'attributes' => array(),
              ));
              break;
            case 'temperature':
              $suffix = $degrees == 'celsius' ? 'C' : 'F';
              $rows[$field][] = $day['high'][$degrees] . '&deg;' . $suffix . ' / ' . $day['low'][$degrees] . '&deg;' . $suffix;
              break;
            case 'conditions':
              $rows[$field][] = $day['conditions'];
              break;
            case 'rain':
              $rows[$field][] = $day['pop'] . '% ' . t('rain');
              break;
            case 'wind':
              $windspeed_unit = variable_get('wunderground_weather_windspeed', 'kph');
              switch ($windspeed_unit) {
                case 'mph':
                  $windspeed = $day['avewind']['mph'] . ' ' . t('mph');
                  break;
                case 'bft':
                  $windspeed = _wunderground_weather_speed_to_beaufort($day['avewind']['kph'], 'kph') . ' ' . t('bft');
                  break;
                default:
                  $windspeed = $day['avewind']['kph'] . ' ' . t('km/h');
                  break;
              }
              $rows[$field][] = $windspeed;
              break;
          }
        }
      }
    }
  }

  // Variables for hook_table.
  $variables = array(
    'header' => $header,
    'rows' => $rows,
    'attributes' => array(),
    'caption' => '',
    'colgroups' => array(),
    'sticky' => FALSE,
    'empty' => '',
  );

  // Return a table.
  return theme('table', $variables);
}

/**
 * Get current weather conditions and return them.
 *
 * @return string
 *   Html for the current conditions block.
 */
function wunderground_weather_get_current($block_number) {

  // Get data from cache or Wunderground directly.
  $weather = _wunderground_weather_cache('current', $block_number);
  $degrees = variable_get('wunderground_weather_degrees', 'celsius');
  $degrees_key = $degrees == 'celsius' ? 'c' : 'f';
  $suffix = strtoupper($degrees_key);

  // Check if data is received.
  if ($weather['current_observation']) {

    // Calculate windspeed.
    $windspeed_unit = variable_get('wunderground_weather_windspeed', 'kph');
    switch ($windspeed_unit) {
      case 'mph':
        $windspeed = $weather['current_observation']['wind_mph'] . ' ' . t('mph');
        break;
      case 'bft':
        $windspeed = _wunderground_weather_speed_to_beaufort($weather['current_observation']['wind_kph'], 'kph') . ' ' . t('bft');
        break;
      default:
        $windspeed = $weather['current_observation']['wind_kph'] . ' ' . t('km/h');
        break;
    }
    $unit = variable_get('wunderground_weather_distance', 'km');
    $distance = $weather['current_observation']['visibility_' . $unit];
    $visibility = $distance == 'N/A' ? $distance : $distance . ' ' . $unit;

    // Build list items.
    $items = array();
    $serialized_fields = variable_get('wunderground_weather_current_' . $block_number . '_fields');
    $block_fields = unserialize($serialized_fields);
    foreach (element_children($block_fields, TRUE) as $field) {
      if ($block_fields[$field]['#enabled'] == 1) {
        switch ($field) {
          case 'weather':
            $items[$field] = $weather['current_observation']['weather'];
            break;
          case 'temperature':
            $items[$field] = t('Temperature: !temp&deg;', array(
              '!temp' => $weather['current_observation']['temp_' . $degrees_key],
            )) . $suffix;
            break;
          case 'feels_like':
            $items[$field] = t('Feels like: !temp&deg;', array(
              '!temp' => $weather['current_observation']['feelslike_' . $degrees_key],
            )) . $suffix;
            break;
          case 'wind':
            $items[$field] = t('Wind') . ': ' . $windspeed;
            break;
          case 'visibility':
            $items[$field] = t('Visibility') . ': ' . $visibility;
            break;
          case 'uv':
            $items[$field] = t('UV index') . ': ' . $weather['current_observation']['UV'];
            break;
        }
      }
    }

    // Get an unorderd list.
    $list = array(
      'title' => '',
      'type' => 'ul',
      'items' => $items,
      'attributes' => array(
        'class' => array(
          'current-weather-summary',
        ),
      ),
    );
    $summary = theme('item_list', $list);

    // Get the weather icon.
    $icon = $weather['current_observation']['icon'];
    $icon_set = variable_get('wunderground_weather_current_icons_' . $block_number, 'a');
    $icon_url = _wunderground_weather_get_icon_url($icon, $icon_set);
    $variables = array(
      'image' => theme('image', array(
        'path' => $icon_url,
        'alt' => t('Weather in !city', array(
          '!city' => variable_get('wunderground_weather_screen', ''),
        )),
        'title' => t('Weather in !city', array(
          '!city' => variable_get('wunderground_weather_screen', ''),
        )),
        'attributes' => array(),
      )),
      'summary' => $summary,
    );
    $output = theme('wunderground_weather_current', $variables);
  }
  else {

    // Return message if no data is retrieved.
    $output = t('No current weather data available.');
    if (user_access('administer wunderground weather')) {
      $configure_path = 'admin/structure/block/manage/wunderground_weather/wunderground_weather_current_' . $block_number . '/configure';
      $output .= ' ' . l(t('Configure this block'), $configure_path);
    }
  }
  return $output;
}

/**
 * Get current weather from Wunderground.
 */
function wunderground_weather_get_current_data($block_number = '') {
  $location = variable_get('wunderground_weather_location_current_' . $block_number, FALSE);
  if ($location) {
    preg_match('#\\[(.*?)\\]#', $location, $match);
    $path = $match[1];
    $options = array(
      'key' => variable_get('wunderground_weather_api_key', ''),
      'data_feature' => 'conditions',
      'language' => 'lang:' . strtoupper(variable_get('wunderground_weather_language', 'EN')),
      'path' => $path,
    );

    // Get data from wunderground.
    $data = wunderground_weather_http_request($options, $path);
  }
  else {
    $data['current_observation'] = FALSE;
  }
  return $data;
}

/**
 * Make a new http request.
 *
 * @param array $options
 *   Array to build the request uri.
 *
 * @return array
 *   Array of returned data or FALSE if something went wrong.
 */
function wunderground_weather_http_request($options, $path) {
  $request_url = 'http://api.wunderground.com/api';
  foreach ($options as $argument) {
    $request_url .= '/' . $argument;
  }
  $request_url .= '.json';

  // Get data from wunderground.
  $response = drupal_http_request($request_url);
  if ($response->code == 200) {
    $data = drupal_json_decode($response->data);
    if (isset($data['response']['error'])) {
      $variables = array(
        '%message' => $data['response']['error']['description'],
        '%location' => $path,
      );
      watchdog('wunderground_weather', '%message: %location', $variables, WATCHDOG_WARNING);
      return FALSE;
    }
    else {

      // Return data from Wunderground.
      return $data;
    }
  }
  else {
    $message = 'Something went wrong while making a http request to Wunderground: %error';
    watchdog('wunderground_weather', $message, array(
      '%error' => 'Error ' . $response->code,
    ), WATCHDOG_ERROR);
    return FALSE;
  }
}

/**
 * Retrieve data from cache or make a new http request.
 *
 * @param string $type
 *   Current weather conditions or weather forecasts.
 *
 * @return array
 *   An array containing all weather data for a block.
 */
function _wunderground_weather_cache($type, $block_number) {
  global $language;
  $langcode = $language->language;

  // Check if we need to use cache.
  if (variable_get('wunderground_weather_cache', 1)) {

    // Get data from cache.
    $cache = cache_get('wunderground_weather_' . $type . '_' . $block_number . '_' . $langcode);
    if ($cache && $cache->expire > time()) {
      $weather = $cache->data;
    }
    else {

      // Get new data from Wunderground and store in the cache.
      $weather = call_user_func('wunderground_weather_get_' . $type . '_data', $block_number);
      $expire = time() + variable_get('wunderground_weather_cache_expire', 86400);
      cache_set('wunderground_weather_' . $type . '_' . $block_number . '_' . $langcode, $weather, 'cache', $expire);
    }
  }
  else {
    $weather = call_user_func('wunderground_weather_get_' . $type . '_data', $block_number);
  }
  $weather['block_number'] = $block_number;
  return $weather;
}

/**
 * Autocomplete function to get locations from the Wunderground database.
 *
 * @param string $text
 *   Input from the autocomplete widget.
 */
function wunderground_weather_location_autocomplete($text = '') {
  $query = urlencode($text);
  $request_url = 'http://autocomplete.wunderground.com/aq?query=' . $query;

  // Get data from wunderground.
  $response = drupal_http_request($request_url);
  if ($response->code == 200) {
    $data = drupal_json_decode($response->data);
  }

  // Extract key and value from the returned array.
  $results = array();
  foreach ($data['RESULTS'] as $result) {
    if (!isset($result['l']) && isset($result['ll'])) {
      $location = str_replace(' ', ',', $result['ll']);
      $geolookup_response = wunderground_weather_geolookup($location);
      $geolookup_data = drupal_json_decode($geolookup_response->data);
      if (isset($geolookup_data['error'])) {
        continue;
      }
      else {
        $result['l'] = $geolookup_data['location']['l'];
      }
    }
    $results[$result['name'] . ' [' . $result['l'] . ']'] = $result['name'];
  }

  // Return as json.
  drupal_json_output($results);
}

/**
 * Returns an array of available fields for the weather forecast block.
 *
 * @return array
 *   An array of fields.
 */
function wunderground_weather_forecast_fields() {
  return array(
    'image' => t('Weather icons'),
    'conditions' => t('Weather description'),
    'temperature' => t('Temperature'),
    'rain' => t('Chance of rain'),
    'wind' => t('Wind speed'),
  );
}

/**
 * Returns an array of available fields for the current conditions block.
 *
 * @return array
 *   An array of fields.
 */
function wunderground_weather_current_fields() {
  return array(
    'feels_like' => t('Feels like'),
    'temperature' => t('Temperature'),
    'uv' => t('UV index'),
    'visibility' => t('Visibility'),
    'weather' => t('Weather description'),
    'wind' => t('Wind speed'),
  );
}

/**
 * @param $location
 *   Location to get geolookup data for.
 *
 * @return bool|object|\stdClass
 *   Response from Wunderground Weather geolookup.
 *
 * @see http://www.wunderground.com/weather/api/d/docs?d=data/geolookup
 */
function wunderground_weather_geolookup($location) {
  $response = FALSE;
  $request_url = 'http://api.wunderground.com/api';
  $api_key = variable_get('wunderground_weather_api_key');
  if ($api_key) {
    $request_url .= '/' . $api_key . '/geolookup/q/' . $location . '.json';
    $response = drupal_http_request($request_url);
  }
  return $response;
}

/**
 * Generate a url to an icon a an icon set.
 *
 * @param string $icon
 *   The name of the icon.
 * @param $icon_set
 *   The name of the icon set.
 *
 * @return string
 *   The url of the requested icon.
 */
function _wunderground_weather_get_icon_url($icon, $icon_set) {
  $path = drupal_get_path('module', 'wunderground_weather') . '/icons/' . $icon_set;
  $icon_url = $path . '/' . $icon . '.gif';
  return $icon_url;
}

/**
 * Get a sample of icons of a icon set.
 *
 * @param string $set
 *   The letter to identify an icon set.
 * @return string
 *  A div containing a sample of icons from an icon set.
 */
function _wunderground_weather_get_icons_sample($icon_set) {
  $path = drupal_get_path('module', 'wunderground_weather') . '/icons/' . $icon_set;
  $files = scandir($path);
  $sample = array(
    $files[8],
    $files[9],
    $files[15],
    $files[18],
    $files[20],
  );
  $sample_icons = array();
  foreach ($sample as $file) {
    $sample_icons[] = theme('image', array(
      'path' => $path . '/' . $file,
    ));
  }
  $output = '<div>' . implode(' ', $sample_icons) . '</div>';
  return $output;
}

/**
 * Convert wind speed to beaufort.
 *
 * @param int $speed
 *   Windspeed in kp/h or m/h.
 *
 * @param string $unit
 *   Windspeed unit.
 *
 * @return int
 *   Windspeed in Bft.
 */
function _wunderground_weather_speed_to_beaufort($speed, $unit) {
  $speed = $unit == 'kph' ? $speed : $speed * 1.6;
  switch (TRUE) {
    case $speed < 1:
      $bft = 0;
      break;
    case $speed < 5.6:
      $bft = 1;
      break;
    case $speed < 12:
      $bft = 2;
      break;
    case $speed < 20:
      $bft = 3;
      break;
    case $speed < 29:
      $bft = 4;
      break;
    case $speed < 39:
      $bft = 5;
      break;
    case $speed < 50:
      $bft = 6;
      break;
    case $speed < 62:
      $bft = 7;
      break;
    case $speed < 75:
      $bft = 8;
      break;
    case $speed < 89:
      $bft = 9;
      break;
    case $speed < 103:
      $bft = 10;
      break;
    case $speed < 118:
      $bft = 11;
      break;
    case $speed >= 118:
      $bft = 12;
      break;
    default:
      $bft = 100;
      break;
  }
  return $bft;
}

/**
 * An array of all supported languages by Wunderground Weather.
 *
 * @return array
 *   All supported languages by the Wunderground API in an array.
 */
function _wunderground_weather_languages() {
  return array(
    'AF' => 'Afrikaans',
    'AL' => 'Albanian',
    'AR' => 'Arabic',
    'HY' => 'Armenian',
    'AZ' => 'Azerbaijani',
    'EU' => 'Basque',
    'BY' => 'Belarusian',
    'BU' => 'Bulgarian',
    'LI' => 'British English',
    'MY' => 'Burmese',
    'CA' => 'Catalan',
    'CN' => 'Chinese - Simplified',
    'TW' => 'Chinese - Traditional',
    'CR' => 'Croatian',
    'CZ' => 'Czech',
    'DK' => 'Danish',
    'DV' => 'Dhivehi',
    'NL' => 'Dutch',
    'EN' => 'English',
    'EO' => 'Esperanto',
    'ET' => 'Estonian',
    'FA' => 'Farsi',
    'FI' => 'Finnish',
    'FR' => 'French',
    'FC' => 'French Canadian',
    'GZ' => 'Galician',
    'DL' => 'German',
    'KA' => 'Georgian',
    'GR' => 'Greek',
    'GU' => 'Gujarati',
    'HT' => 'Haitian Creole',
    'IL' => 'Hebrew',
    'HI' => 'Hindi',
    'HU' => 'Hungarian',
    'IS' => 'Icelandic',
    'IO' => 'Ido',
    'ID' => 'Indonesian',
    'IR' => 'Irish Gaelic',
    'IT' => 'Italian',
    'JP' => 'Japanese',
    'JW' => 'Javanese',
    'KM' => 'Khmer',
    'KR' => 'Korean',
    'KU' => 'Kurdish',
    'LA' => 'Latin',
    'LV' => 'Latvian',
    'LT' => 'Lithuanian',
    'ND' => 'Low German',
    'MK' => 'Macedonian',
    'MT' => 'Maltese',
    'GM' => 'Mandinka',
    'MI' => 'Maori',
    'MR' => 'Marathi',
    'MN' => 'Mongolian',
    'NO' => 'Norwegian',
    'OC' => 'Occitan',
    'PS' => 'Pashto',
    'GN' => 'Plautdietsch',
    'PL' => 'Polish',
    'BR' => 'Portuguese',
    'PA' => 'Punjabi',
    'RO' => 'Romanian',
    'RU' => 'Russian',
    'SR' => 'Serbian',
    'SK' => 'Slovak',
    'SL' => 'Slovenian',
    'SP' => 'Spanish',
    'SI' => 'Swahili',
    'SW' => 'Swedish',
    'CH' => 'Swiss',
    'TL' => 'Tagalog',
    'TT' => 'Tatarish',
    'TH' => 'Thai',
    'TR' => 'Turkish',
    'TK' => 'Turkmen',
    'UA' => 'Ukrainian',
    'UZ' => 'Uzbek',
    'VU' => 'Vietnamese',
    'CY' => 'Welsh',
    'SN' => 'Wolof',
    'JI' => 'Yiddish - transliterated',
    'YI' => 'Yiddish - unicode',
  );
}

Functions

Namesort descending Description
theme_wunderground_weather_field_drag Theme function to create draggable fields.
theme_wunderground_weather_forecast Theme function to render weather forecast block.
wunderground_weather_block_configure Implements hook_block_configure().
wunderground_weather_block_configure_location_fields Attach location fields to the block configure forms.
wunderground_weather_block_info Implements hook_block_info().
wunderground_weather_block_save Implements hook_block_save().
wunderground_weather_block_view Implements hook_block_view().
wunderground_weather_current_fields Returns an array of available fields for the current conditions block.
wunderground_weather_forecast_fields Returns an array of available fields for the weather forecast block.
wunderground_weather_geolookup
wunderground_weather_get_current Get current weather conditions and return them.
wunderground_weather_get_current_data Get current weather from Wunderground.
wunderground_weather_get_forecast Get forecast data and return a themed table.
wunderground_weather_get_forecast_data Get weather forecast from Wunderground.
wunderground_weather_help Implements hook_help().
wunderground_weather_http_request Make a new http request.
wunderground_weather_location_autocomplete Autocomplete function to get locations from the Wunderground database.
wunderground_weather_menu Implements hook_menu().
wunderground_weather_permission Implements hook_permission().
wunderground_weather_theme Implements hook_theme().
wunderground_weather_variable_info Implements hook_variable_info().
_wunderground_weather_cache Retrieve data from cache or make a new http request.
_wunderground_weather_get_icons_sample Get a sample of icons of a icon set.
_wunderground_weather_get_icon_url Generate a url to an icon a an icon set.
_wunderground_weather_languages An array of all supported languages by Wunderground Weather.
_wunderground_weather_speed_to_beaufort Convert wind speed to beaufort.