farmOS/modules/farm/farm_map/farm_map.module

343 lines
8.6 KiB
Plaintext

<?php
/**
* @file
* Code for the Farm Maps feature.
*/
include_once 'farm_map.block.inc';
include_once 'farm_map.geo.inc';
/**
* Implements hook_hook_info().
*/
function farm_map_hook_info() {
$hooks['farm_map_behaviors'] = array(
'group' => 'farm_map',
);
$hooks['farm_map_behavior_settings'] = array(
'group' => 'farm_map',
);
$hooks['farm_map_view'] = array(
'group' => 'farm_map',
);
return $hooks;
}
/**
* Implements hook_permission().
*/
function farm_map_permission() {
$perms = array(
'administer farm_map module' => array(
'title' => t('Administer farm map module'),
),
);
return $perms;
}
/**
* Implements hook_farm_access_perms().
*/
function farm_map_farm_access_perms($role) {
$perms = array();
// Load the list of farm roles.
$roles = farm_access_roles();
// If this role has 'config' access,grant access to map configuration.
if (!empty($roles[$role]['access']['config'])) {
$perms[] = 'administer farm_map module';
}
return $perms;
}
/**
* Implements hook_menu().
*/
function farm_map_menu() {
// Map configuration form.
$items['admin/config/farm/map'] = array(
'title' => 'Map',
'description' => 'Map configuration settings.',
'page callback' => 'drupal_get_form',
'page arguments' => array('farm_map_settings_form'),
'access arguments' => array('administer farm_map module'),
);
return $items;
}
/**
* Implements hook_libraries_info().
*/
function farm_map_libraries_info() {
$libraries['farmOS-map'] = array(
'name' => 'farmOS Map',
'vendor url' => 'https://github.com/farmOS/farmOS-map',
'download url' => 'https://github.com/farmOS/farmOS-map/releases',
'version arguments' => array(
'file' => 'farmOS-map.js',
'pattern' => '/farmOS-map v([0-9\.]+)/',
'lines' => 1,
),
'files' => array(
'js' => array('farmOS-map.js'),
),
);
return $libraries;
}
/**
* Implements hook_theme().
*/
function farm_map_theme($existing, $type, $theme, $path) {
return array(
'farm_map' => array(
'render element' => 'element',
),
);
}
/**
* Returns HTML that wraps the farm map..
*/
function theme_farm_map(&$vars) {
// Get the element.
$element = $vars['element'];
// Load the farmOS-map.js library.
libraries_load('farmOS-map');
// Get the map name (default to 'farm_map').
if (empty($element['#map_name'])) {
$element['#map_name'] = 'farm_map';
}
$map_name = $element['#map_name'];
// Generate a map div ID, if one wasn't provided.
$id = drupal_html_id($map_name);
if (!empty($element['#attributes']['id'])) {
$id = $element['#attributes']['id'];
}
else {
$element['#attributes']['id'] = $id;
}
// Add 'farm-map' CSS class.
if (empty($element['#attributes']['class']) || !in_array('farm-map', $element['#attributes']['class'])) {
$element['#attributes']['class'][] = 'farm-map';
}
// Create a settings array to be passed to JavaScript.
$settings = array(
'farm_map' => array(),
);
// Add a setting that defines the base path of the site.
// We do this instead of using Drupal.settings.basePath in Javascript
// because that variable does not take into account whether or not clean
// URLs are enabled.
$settings['farm_map']['base_path'] = str_replace('farm', '', url('farm'));
// Load the system of measurement, and save it to settings.
$system_of_measurement = farm_quantity_system_of_measurement();
$settings['farm_map']['units'] = $system_of_measurement;
// If WKT is set, add it to the settings associated with the element ID.
if (isset($element['#wkt'])) {
$settings['farm_map']['wkt'][$id] = $element['#wkt'];
}
// Add the JavaScript settings.
drupal_add_js($settings, 'setting');
// Add farm_map.js, which will run farmOS.map.create().
drupal_add_js(drupal_get_path('module', 'farm_map') . '/js/farm_map.js');
// Add farm_map.css.
drupal_add_css(drupal_get_path('module', 'farm_map') . '/css/farm_map.css');
// Allow other modules to perform logic.
module_invoke_all('farm_map_view', $map_name, $element);
// Return a simple div with attributes.
return '<div' . drupal_attributes($element['#attributes']) . '></div>';
}
/**
* Implements hook_element_info().
*/
function farm_map_element_info() {
return array(
'farm_map' => array(
'#theme' => 'farm_map',
),
);
}
/**
* Build a map render array.
*
* @param string $map_name
* The machine name of the map.
* @param bool $fieldset
* Whether or not to wrap the map in a fieldset.
* @param string $title
* Whether or not to wrap the map in a fieldset.
* @param bool $collapsed
* Whether or not to collapse the fieldset by default.
*
* @return array
* Returns a Drupal render array.
*/
function farm_map_build($map_name, $fieldset = FALSE, $title = '', $collapsed = FALSE) {
// Build the map.
$build = array(
'#type' => 'farm_map',
'#map_name' => $map_name,
);
// Wrap the map in a fieldset, if desired.
if (!empty($fieldset)) {
// Create the fieldset.
$build = array(
'#type' => 'fieldset',
'#title' => $title,
'#collapsible' => TRUE,
'#collapsed' => $collapsed,
'farm_map' => $build,
);
// Add 'collapsible' and 'collapsed' classes. This is necessary when
// rendering the fieldset outside of a form.
// See: https://www.drupal.org/node/1099132
drupal_add_library('system', 'drupal.collapse');
$build['#attributes']['class'][] = 'collapsible';
$build['#attributes']['class'][] = 'collapsed';
}
// Return the build.
return $build;
}
/**
* Add a farmOS-map behavior to the page.
*
* @param string $behavior
* The behavior name.
* @param array $settings
* Optionally provide settings to override defaults.
*/
function farm_map_add_behavior($behavior, $settings = array()) {
// Ask modules for behaviors.
$hook = 'farm_map_behaviors';
$modules = module_implements($hook);
foreach ($modules as $module) {
// Get the module's behaviors.
$behaviors = module_invoke($module, $hook);
// If the desired behavior isn't defined, skip.
if (!(array_key_exists($behavior, $behaviors) && !empty($behaviors[$behavior]['js']))) {
continue;
}
// If the module defines settings for the behavior, add them as JS settings.
$settings_hook = 'farm_map_behavior_settings';
$default_settings = array();
if (function_exists($module . '_' . $settings_hook)) {
$default_settings = module_invoke($module, $settings_hook, $behavior);
}
$settings = array_merge($default_settings, $settings);
if (!empty($settings)) {
drupal_add_js(array(
'farm_map' => array(
'behaviors' => array(
$behavior => $settings,
),
),
), array('type' => 'setting'));
}
// Add the behavior JS to the page.
$path = drupal_get_path('module', $module) . '/' . $behaviors[$behavior]['js'];
drupal_add_js($path);
}
}
/**
* Map settings form.
*/
function farm_map_settings_form($form, &$form_state) {
$form = array();
return system_settings_form($form);
}
/**
* Extract geometries from an entity.
*
* @param $entity_type
* The entity type machine name.
* @param $entity
* The entity object.
*
* @return array
* Return an array of geometry strings in WKT format. An associative array
* is allowed, and the keys can be used to differentiate multiple geometries
* from the same entity.
*/
function farm_map_entity_geometries($entity_type, $entity) {
// Ask modules to extract geometries.
return module_invoke_all('farm_map_entity_geometries', $entity_type, $entity);
}
/**
* Implements hook_farm_map_geometries().
*/
function farm_map_farm_map_entity_geometries($entity_type, $entity) {
$geometries = array();
// Find geometry in the standard geofield.
if (!empty($entity->field_farm_geofield[LANGUAGE_NONE][0]['geom'])) {
$geometries[] = $entity->field_farm_geofield[LANGUAGE_NONE][0]['geom'];
}
return $geometries;
}
/**
* Helper function for populating the geometry field of an entity.
*
* @param Entity $entity
* The entity object.
* @param array $geoms
* An array of geometry strings in WKT format.
*/
function farm_map_geofield_populate(&$entity, $geoms = array()) {
// If no geometries were found, bail.
if (empty($geoms)) {
return;
}
// Combine the WKT geometries into a single GeoPHP geometry.
$geometry = farm_map_combine_geoms($geoms);
// If that didn't work, bail.
if (empty($geometry)) {
return;
}
// Save the combined geometry to the movement log.
if (!empty($geometry)) {
$entity->field_farm_geofield[LANGUAGE_NONE][0] = geofield_get_values_from_geometry($geometry);
}
}