You are here

yamaps.module in Yandex.Maps 7

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

Yandex Maps module main file.

File

yamaps.module
View source
<?php

/**
 * @file
 * Yandex Maps module main file.
 */

/**
 * Constants.
 */
define('YAMAPS_API_URL', _yamaps_api_url());
define('YAMAPS_STATIC_API_URL', _yamaps_static_api_url());
define('YAMAPS_GEOCODER_URL', _yamaps_geocoder_url());
define('YAMAPS_LEGAL_AGREEMENT_URL', _yamaps_legal_agreement_url());
define('YAMAPS_DYNAMIC_FORMATTER', 'field_yamaps_formatter_dynamic');
define('YAMAPS_STATIC_FORMATTER', 'field_yamaps_formatter_static');
define('YAMAPS_TEXT_FORMATTER', 'field_yamaps_formatter_text');
define('YAMAPS_API_LANGUAGE', 'ru-RU');
define('YAMAPS_DEFAULT_BLOCK_DELTA', 'yamaps');
define('YAMAPS_DEFAULT_BLOCK_AMOUNT', 1);
define('YAMAPS_DEFAULT_BLOCK_MAP_WIDTH', '168px');
define('YAMAPS_DEFAULT_BLOCK_MAP_HEIGHT', '200px');
define('YAMAPS_DEFAULT_ADMIN_UI_MAP_WIDTH', '100%');
define('YAMAPS_DEFAULT_ADMIN_UI_MAP_HEIGHT', '400px');
define('YAMAPS_DEFAULT_DYNAMIC_WIDTH', '100%');
define('YAMAPS_DEFAULT_DYNAMIC_HEIGHT', '400px');
define('YAMAPS_DEFAULT_STATIC_WIDTH', 640);
define('YAMAPS_DEFAULT_STATIC_HEIGHT', 400);
define('YAMAPS_DEFAULT_OPEN_MAP_TEXT', 'Open map');
define('YAMAPS_DEFAULT_CLOSE_MAP_TEXT', 'Close map');

/**
 * Includes.
 */
module_load_include('inc', 'yamaps', 'yamaps.functions');
module_load_include('inc', 'yamaps', 'inc/yamaps.formatter');
module_load_include('inc', 'yamaps', 'inc/yamaps.widget');
module_load_include('inc', 'yamaps', 'inc/yamaps.block');

/**
 * Implements hook_menu().
 */
function yamaps_menu() {
  return [
    'admin/config/services/yamaps' => [
      'title' => 'Yandex Maps configuration',
      'description' => 'Yandex Maps configuration',
      'page callback' => 'drupal_get_form',
      'page arguments' => [
        'yamaps_settings_page',
      ],
      'access arguments' => [
        'administer yamaps settings',
      ],
      'file' => 'yamaps.admin.inc',
      'type' => MENU_LOCAL_TASK,
    ],
  ];
}

/**
 * Implements hook_permission().
 */
function yamaps_permission() {
  return [
    'administer yamaps settings' => [
      'title' => t('Administer Yandex Maps settings'),
      'description' => t('Manage Yandex Maps configuration parameters.'),
    ],
  ];
}

/**
 * Implements hook_element_info().
 */
function yamaps_element_info() {
  return [
    'yamaps_field' => [
      '#input' => TRUE,
      '#theme_wrappers' => [
        'form_element',
      ],
    ],
  ];
}

/**
 * Implements hook_library().
 */
function yamaps_library() {

  // Users language.
  global $language;

  // Module path.
  $path = drupal_get_path('module', 'yamaps') . '/misc/';

  // Weight counter.
  $w = 10;

  // API url.
  $api_url = url(YAMAPS_API_URL, [
    'absolute' => TRUE,
    'query' => [
      'load' => 'package.full',
      'lang' => YAMAPS_API_LANGUAGE,
      'wizard' => 'Drupal_yamaps_' . $language->language,
      'apikey' => variable_get('yamaps_api_key', ''),
    ],
  ]);
  $libraries['yamaps.full'] = [
    'title' => 'Yandex maps. Version for dynamic map.',
    'version' => '2.x',
    'js' => [
      $api_url => [
        'type' => 'external',
        'scope' => 'header',
        'weight' => $w++,
      ],
      $path . 'yamaps.init.js' => [
        'scope' => 'footer',
        'weight' => $w++,
      ],
      $path . 'yamaps.layouts.js' => [
        'scope' => 'footer',
        'weight' => $w++,
      ],
      $path . 'yamaps.placemark.js' => [
        'scope' => 'footer',
        'weight' => $w++,
      ],
      $path . 'yamaps.line.js' => [
        'scope' => 'footer',
        'weight' => $w++,
      ],
      $path . 'yamaps.polygon.js' => [
        'scope' => 'footer',
        'weight' => $w++,
      ],
      $path . 'yamaps.route.js' => [
        'scope' => 'footer',
        'weight' => $w++,
      ],
      $path . 'yamaps.maps.js' => [
        'scope' => 'footer',
        'weight' => $w++,
      ],
      $path . 'yamaps.run.js' => [
        'scope' => 'footer',
        'weight' => $w++,
      ],
    ],
    'css' => [
      $path . 'yamaps.css' => [],
    ],
  ];
  return $libraries;
}

/**
 * Implements hook_help().
 */
function yamaps_help($path, $arg) {
  if ($path == 'admin/help#yamaps') {
    $output = '<h3>' . t('About') . '</h3>';
    $about = [
      t('Project contains a set of modules for Drupal 7 that use Yandex.Maps service available at !link.', [
        '!link' => l(t('http://maps.yandex.com/'), 'http://maps.yandex.com/'),
      ]),
      t('Uses !api (API 2.x).', [
        '!api' => l(t('http://api.yandex.ru/maps/'), 'http://api.yandex.ru/maps/'),
      ]),
      t('Project page: !link.', [
        '!link' => l(t('https://drupal.org/project/yamaps'), 'https://drupal.org/project/yamaps'),
      ]),
      t('To submit bug reports and feature suggestions, or to track changes: !link.', [
        '!link' => l(t('https://drupal.org/project/issues/yamaps'), 'https://drupal.org/project/issues/yamaps'),
      ]),
    ];
    $output .= yamaps_wrap_items($about, '<p>', '</p>');
    $output .= '<h3>' . t('Modules') . '</h3>';
    $modules = [
      t('<strong>Yandex Maps</strong> (main module, description provided below).'),
      t('<strong>Yandex Maps Example</strong> (submodule). Feature-based module which demonstrates example content type containing "Yandex Map" field and view to output maps.'),
      t('<strong>For demo purposes only!</strong>'),
      t('<strong>Yandex Maps Views</strong> (submodule). Enables integration with Views for "Yandex Map" field and provides "Yandex Maps" display plugin.'),
    ];
    $output .= theme('item_list', [
      'items' => $modules,
    ]);
    $output .= '<h3>' . t('Options') . '</h3>';
    $options = [
      t('Map can be displayed as interactive object ("dynamic map") or image ("static map").'),
      t('Map can be displayed by click on the "button" with configurable text.'),
      t('Change the type, size and center of the map.'),
      t('Add placemarks, select label color, change texts, add labels using the search string.'),
      t('Draw polylines, chose colors, transparency, line width, text.'),
      t('Draw polygons, chose colors and line width, fill color, transparency, texts.'),
      t('Add a route.'),
      t('Displays traffic jams.'),
      t('Auto zoom.'),
      t('Use clusterer.'),
    ];
    $output .= theme('item_list', [
      'items' => $options,
    ]);
    $output .= '<h3>' . t('Requirements, installation and uninstallation') . '</h3>';
    $reqirements = [
      t('Requires core "block" and "field" modules.'),
      t("Modules doesn't contain specific installation / uninstallation instructions."),
      t('Installing Drupal module: !link.', [
        '!link' => l(t('https://drupal.org/documentation/install/modules-themes/modules-7'), 'https://drupal.org/documentation/install/modules-themes/modules-7'),
      ]),
    ];
    $output .= yamaps_wrap_items($reqirements, '<p>', '</p>');
    $output .= '<h3>' . t('Configuration and usage') . '</h3>';
    $config_fields = [
      t('Module provides configurable "Yandex Maps" field, which can be added to any type of Drupal content.'),
      t('Field may accept "Dynamic" or "Static" formats.'),
      t('"Dynamic" format means that map is displayed as interactive object.'),
      t('"Static" format means that map is displayed as regular image.'),
      t('To add "Yandex Maps" field perform following steps:'),
    ];
    $output .= yamaps_wrap_items($config_fields, '<p>', '</p>');
    $config_fields_options = [
      t('Navigate to !content_type and select content type.', [
        '!content_type' => l(t('"Content Types" page'), 'admin/structure/types'),
      ]),
      t('Navigate to admin/structure/types/manage/{CONTENT-TYPE}/fields ("Manage Fields" page) of the selected content type.'),
      t('Configure and add field of "Yandex map" type.'),
      t('Navigate to admin/structure/types/manage/{CONTENT-TYPE}/display ("Manage Display" page) of the selected content type.'),
      t('Configure field format.'),
    ];
    $output .= theme('item_list', [
      'items' => $config_fields_options,
    ]);
    $config_blocks = [
      t('Module also provides configurable amount of "Yandex Maps" blocks to display maps in any regions of the website.'),
      t('Block may also present map as a "Dynamic" (interactive object) or "Static" (image).'),
      t('To add "Yandex Maps" block perform following steps:'),
    ];
    $output .= yamaps_wrap_items($config_blocks, '<p>', '</p>');
    $config_blocks_options = [
      t('Navigate to !yamaps_admin and set required amount of "Yandex Maps" blocks.', [
        '!yamaps_admin' => l(t('"Yandex Maps" configuration page'), 'admin/config/services/yamaps'),
      ]),
      t('Navigate to !blocks_page, scroll down to find "Disabled" section and find block called "Yandex Map #{NUMBER}".', [
        '!blocks_page' => l(t('"Blocks" page'), 'admin/structure/block'),
      ]),
      t('Configure the block and pull it into the required region.'),
    ];
    $output .= theme('item_list', [
      'items' => $config_blocks_options,
    ]);
    $output .= '<h3>' . t('Information') . '</h3>';
    $information = [
      t('Demo: !link.', [
        '!link' => l(t('http://yandex.xyz.tom.ru/'), 'http://yandex.xyz.tom.ru/'),
      ]),
      t('Blog post: !link.', [
        '!link' => l(t('http://yandex.xyz.tom.ru/'), 'http://yandex.xyz.tom.ru/'),
      ]),
    ];
    $output .= theme('item_list', [
      'items' => $information,
    ]);
    return $output;
  }
}

/**
 * Implements hook_field_info().
 */
function yamaps_field_info() {
  return [
    'field_yamaps' => [
      'label' => t('Yandex map'),
      'default_widget' => 'yamaps_field',
      'default_formatter' => YAMAPS_DYNAMIC_FORMATTER,
      'settings' => [
        'display_options' => [
          'display_type' => 'map',
          'open_button_text' => YAMAPS_DEFAULT_OPEN_MAP_TEXT,
          'height' => YAMAPS_DEFAULT_ADMIN_UI_MAP_HEIGHT,
          'width' => YAMAPS_DEFAULT_ADMIN_UI_MAP_WIDTH,
        ],
      ],
    ],
  ];
}

/**
 * Implements hook_field_is_empty().
 */
function yamaps_field_is_empty($item, $field) {
  if ($field['type'] == 'field_yamaps') {
    return empty($item['coords']);
  }
}

/**
 * Implements hook_field_settings_form().
 */
function yamaps_field_settings_form($field, $instance, $has_data) {
  $settings = $field['settings'];
  $form['display_options'] = [
    '#type' => 'fieldset',
    '#title' => t('Display options'),
    '#tree' => TRUE,
  ];
  $form['display_options']['display_type'] = [
    '#type' => 'radios',
    '#title' => t('Map display style in admin UI for field'),
    '#options' => [
      'map' => t('Map'),
      'map_button' => t('Map opened by button click'),
      'map_without_fields' => t('Map without additional (search, coordinates, etc) fields.'),
    ],
    '#default_value' => $settings['display_options']['display_type'],
    '#required' => FALSE,
    '#description' => t('Configure how to display "Yandex Map" field while creating new / updating material. Applies to admin UI only.'),
  ];
  $form['display_options']['open_button_text'] = [
    '#type' => 'textfield',
    '#title' => t('"Open" button text'),
    '#default_value' => isset($settings['display_options']['open_button_text']) ? $settings['display_options']['open_button_text'] : t(YAMAPS_DEFAULT_OPEN_MAP_TEXT),
    '#required' => FALSE,
    '#description' => t('Specify text to display on button that opens map in case of "Map opened by button click" option. Applies to admin UI only.'),
    '#states' => [
      'visible' => [
        ':input[name="field[settings][display_options][display_type]"]' => [
          'value' => 'map_button',
        ],
      ],
    ],
  ];
  $form['display_options']['close_button_text'] = [
    '#type' => 'textfield',
    '#title' => t('"Close" button text'),
    '#default_value' => isset($settings['display_options']['close_button_text']) ? $settings['display_options']['close_button_text'] : t(YAMAPS_DEFAULT_CLOSE_MAP_TEXT),
    '#required' => FALSE,
    '#description' => t('Specify text to display on button that closes map in case of "Map opened by button click" option. Applies to admin UI only.'),
    '#states' => [
      'visible' => [
        ':input[name="field[settings][display_options][display_type]"]' => [
          'value' => 'map_button',
        ],
      ],
    ],
  ];
  $form['display_options']['width'] = [
    '#title' => t('Map width in admin UI'),
    '#field_suffix' => ' ' . t('in pixels (px) or percentage (%).'),
    '#type' => 'textfield',
    '#default_value' => isset($settings['display_options']['width']) ? $settings['display_options']['width'] : YAMAPS_DEFAULT_ADMIN_UI_MAP_WIDTH,
    '#size' => 5,
    '#element_validate' => [
      'yamaps_field_validate_pixels_percentage',
    ],
    '#required' => TRUE,
    '#description' => t('Set width for the map in field widget of "entity edit" form.'),
  ];
  $form['display_options']['height'] = [
    '#title' => t('Map height in admin UI'),
    '#field_suffix' => ' ' . t('in pixels (px) or percentage (%).'),
    '#type' => 'textfield',
    '#default_value' => isset($settings['display_options']['height']) ? $settings['display_options']['height'] : YAMAPS_DEFAULT_ADMIN_UI_MAP_HEIGHT,
    '#size' => 5,
    '#element_validate' => [
      'yamaps_field_validate_pixels_percentage',
    ],
    '#required' => TRUE,
    '#description' => t('Set height for the map in field widget of "entity edit" form.'),
  ];
  $form['display_options']['controls'] = [
    '#title' => t('Display map controls'),
    '#type' => 'checkbox',
    '#default_value' => isset($settings['display_options']['controls']) ? $settings['display_options']['controls'] : FALSE,
  ];
  $form['display_options']['traffic'] = [
    '#title' => t('Display traffic'),
    '#type' => 'checkbox',
    '#default_value' => isset($settings['display_options']['traffic']) ? $settings['display_options']['traffic'] : FALSE,
  ];
  $form['display_options']['enable_placemarks'] = [
    '#title' => t('Enable placemarks'),
    '#type' => 'checkbox',
    '#default_value' => isset($settings['display_options']['enable_placemarks']) ? $settings['display_options']['enable_placemarks'] : FALSE,
  ];
  $form['display_options']['enable_routes'] = [
    '#title' => t('Enable routes'),
    '#type' => 'checkbox',
    '#default_value' => isset($settings['display_options']['enable_routes']) ? $settings['display_options']['enable_routes'] : FALSE,
  ];
  $form['display_options']['enable_lines'] = [
    '#title' => t('Enable lines'),
    '#type' => 'checkbox',
    '#default_value' => isset($settings['display_options']['enable_lines']) ? $settings['display_options']['enable_lines'] : FALSE,
  ];
  $form['display_options']['enable_polygons'] = [
    '#title' => t('Enable polygons'),
    '#type' => 'checkbox',
    '#default_value' => isset($settings['display_options']['enable_polygons']) ? $settings['display_options']['enable_polygons'] : FALSE,
  ];
  $form['display_options']['clusterer'] = [
    '#title' => t('Use clusterer'),
    '#type' => 'checkbox',
    '#default_value' => isset($settings['display_options']['clusterer']) ? $settings['display_options']['clusterer'] : FALSE,
  ];
  $form['display_options']['auto_zoom'] = [
    '#title' => t('User auto_zoom'),
    '#type' => 'checkbox',
    '#default_value' => isset($settings['display_options']['auto_zoom']) ? $settings['display_options']['auto_zoom'] : FALSE,
  ];
  return $form;
}

/**
 * Implements hook_field_validate().
 */
function yamaps_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
  if ($field['type'] == 'field_yamaps') {

    // Perform validation on empty coordinates only for field
    // attached to entity.
    if ($entity_type && $entity) {
      if ($instance['required']) {
        $items_total = count($items);
        $items_empty = 0;
        foreach ($items as $item) {
          if (empty($item['coords'])) {
            $items_empty++;
          }
        }
        if ($items_total == $items_empty) {
          $errors[$field['field_name']][$langcode][0][] = [
            'error' => 'coords',
            'message' => t('Cooordinates cannot be empty for required field "!field_name".', [
              '!field_name' => $instance['label'],
            ]),
          ];
        }
      }
    }
    else {

      // Validation for fields settings form.
      foreach ($items as $delta => $item) {
        if (empty($item['coords']) && $item['hide'] == 1) {
          $errors[$field['field_name']][$langcode][$delta][] = [
            'error' => 'coords',
            'message' => t('"!field_name" with empty coordinates cannot be hidden by default.', [
              '!field_name' => $instance['label'],
            ]),
          ];
        }
      }
    }
  }
}

/**
 * Provide static API url, use YAMAPS_STATIC_API_URL instead direct calling.
 */
function _yamaps_static_api_url() {
  global $is_https;
  return $is_https ? 'https://static-maps.yandex.ru/1.x/' : 'http://static-maps.yandex.ru/1.x/';
}

/**
 * Provide geocoder url, use YAMAPS_GEOCODER_URL instead direct calling.
 */
function _yamaps_geocoder_url() {
  global $is_https;
  return $is_https ? 'https://geocode-maps.yandex.ru/1.x/' : 'http://geocode-maps.yandex.ru/1.x/';
}

/**
 * Provide legal agreement url, use YAMAPS_LEGAL_AGREEMENT_URL instead direct
 * calling.
 */
function _yamaps_legal_agreement_url() {
  global $is_https;
  return $is_https ? 'https://legal.yandex.ru/maps_api/' : 'http://legal.yandex.ru/maps_api/';
}

/**
 * Provide api url, use YAMAPS_API_URL instead direct calling.
 */
function _yamaps_api_url() {
  global $is_https;
  return $is_https ? 'https://api-maps.yandex.ru/2.1/' : 'http://api-maps.yandex.ru/2.1/';
}

/**
 * Provides list of hex colors.
 */
function yamaps_get_colors() {
  return [
    'blue' => '006cff',
    'lightblue' => '66c7ff',
    'night' => '004056',
    'darkblue' => '00339a',
    'green' => '33cc00',
    'white' => 'ffffff',
    'red' => 'ff0000',
    'orange' => 'ffb400',
    'darkorange' => 'ff6600',
    'yellow' => 'ffea00',
    'violet' => 'b832fd',
    'pink' => 'fd32fb',
  ];
}