'admin/settings/cck_map', 'title' => t('CCK Map Settings'), 'description' => 'Edit CCK Map Settings', 'callback' => 'cck_map_admin_menu', 'access' => user_access('administer CCK Maps'), 'type' => MENU_NORMAL_ITEM, ); } return $items; } function cck_map_admin_menu() { return drupal_get_form('cck_map_admin_form'); //return theme('form', $form); } function cck_map_admin_form() { $form = array(); $key = variable_get('cck_map_key', ''); $form['api_key'] = array( '#type' => 'textfield', '#title' => t('Google Maps API Key.'), '#default_value' => $key ); $form['submit'] = array('#type' => 'submit', '#value' => t('Submit')); $form['#submit']['cck_map_admin_menu_save'] = array(); $form['#method'] = "POST"; return $form; } function cck_map_admin_menu_save($form_id, &$form) { $key = trim(check_plain($form['api_key'])); variable_set('cck_map_key', $key); } function cck_map_form_alter($form_id, &$form) { if ($form_id == '_content_admin_field') { /* */ if ($form['field_type']['#value'] == 'map_location') { unset($form['widget']['default_value_fieldset']); if (!strlen($form['widget']['description']['#value'])) $form['widget']['description']['#value'] = "INSTRUCCIONES: Muevete sobre el mapa con los controles de la izquierda. Una vez situado en el sitio o sitios que desees, haz un click simple sobre el mapa para situar tus iconos. Cuando estŽs listo pincha sobre cada uno de ellos para darles un t’tulo, una descripci—n y seleccionar un icono para ellos."; } } } function cck_map_perm( ) { return array('administer CCK Maps'); } /** * Declare information about a field type. * * @return * An array keyed by field type name. Each element of the array is an associative * array with these keys and values: * - "label": The human-readable label for the field type. */ function cck_map_field_info() { return array( 'map_location' => array('label' => 'Map Location'), ); } /** * Handle the parameters for a field. * * @param $op * The operation to be performed. Possible values: * - "form": Display the field settings form. * - "validate": Check the field settings form for errors. * - "save": Declare which fields to save back to the database. * - "database columns": Declare the columns that content.module should create * and manage on behalf of the field. If the field module wishes to handle * its own database storage, this should be omitted. * - "filters": If content.module is managing the database storage, * this operator determines what filters are available to views. * They always apply to the first column listed in the "database columns" * array. * @param $field * The field on which the operation is to be performed. * @return * This varies depending on the operation. * - The "form" operation should return an array of form elements to add to * the settings page. * - The "validate" operation has no return value. Use form_set_error(). * - The "save" operation should return an array of names of form elements to * be saved in the database. * - The "database columns" operation should return an array keyed by column * name, with arrays of column information as values. This column information * must include "type", the MySQL data type of the column, and may also * include a "sortable" parameter to indicate to views.module that the * column contains ordered information. Details of other information that can * be passed to the database layer can be found at content_db_add_column(). * - The "filters" operation should return an array whose values are 'filters' * definitions as expected by views.module (see Views Documentation). * When proving several filters, it is recommended to use the 'name' * attribute in order to let the user distinguish between them. If no 'name' * is specified for a filter, the key of the filter will be used instead. */ function cck_map_field_settings($op, $field) { switch ($op) { case 'form': $form = array(); return $form; case 'save': return array('lat', 'lon', 'title', 'description', 'image'); break; case 'database columns': $columns = array( 'lat' => array('type' => 'double', 'not null' => TRUE, 'default' => 0), 'lon' => array('type' => 'double', 'not null' => TRUE, 'default' => 0), 'title' => array('type' => 'varchar(255)', 'not null' => false, 'default' => 0), 'description' => array('type' => 'varchar(255)', 'not null' => false, 'default' => 0), 'image' => array('type' => 'varchar(255)', 'not null' => false, 'default' => 0), ); return $columns; case 'filters': return array(); case 'callbacks': return array( 'view' => CONTENT_CALLBACK_CUSTOM, ); break; } } /** * Define the behavior of a field type. * * @param $op * What kind of action is being performed. Possible values: * - "load": The node is about to be loaded from the database. This hook * should be used to load the field. * - "view": The node is about to be presented to the user. The module * should prepare and return an HTML string containing a default * representation of the field. * - "validate": The user has just finished editing the node and is * trying to preview or submit it. This hook can be used to check or * even modify the node. Errors should be set with form_set_error(). * - "submit": The user has just finished editing the node and the node has * passed validation. This hook can be used to modify the node. * - "insert": The node is being created (inserted in the database). * - "update": The node is being updated. * - "delete": The node is being deleted. * @param &$node * The node the action is being performed on. This argument is passed by * reference for performance only; do not modify it. * @param $field * The field the action is being performed on. * @param &$items * An array containing the values of the field in this node. Changes to this variable will * be saved back to the node object. * Note that, in order to ensure consistency, this variable contains an array regardless of * whether field is set to accept multiple values or not. * @return * This varies depending on the operation. * - The "load" operation should return an object containing extra values * to be merged into the node object. * - The "view" operation should return a string containing an HTML * representation of the field data. * - The "insert", "update", "delete", "validate", and "submit" operations * have no return value. * * In most cases, only "view" and "validate" are relevant operations; the rest * have default implementations in content_field() that usually suffice. */ function cck_map_field($op, &$node, $field, &$items, $teaser, $page) { switch ($op) { case 'update': $rowcount = db_fetch_object(db_query("SELECT nid from {cck_map} where nid = %d and vid = %d", $node->nid, $node->vid)); if ($rowcount->nid) { db_query("update {cck_map} set maplat = %f, maplon = %f, mapzoom = %d, maptype ='%s' where nid = %d and vid =%d", $items['maplat'], $items['maplon'], $items['mapzoom'], $items['maptype'], $node->nid, $node->vid); unset($items['maplat']); unset($items['maplon']); unset($items['mapzoom']); unset($items['maptype']); // ???? hay que hacer update de nid y vid???? break; } case 'insert': db_query("insert into {cck_map} (nid, vid, maplat, maplon, mapzoom, maptype) VALUES (%d, %d, %f, %f, %d, '%s')", $node->nid, $node->vid, $items['maplat'], $items['maplon'], $items['mapzoom'], $items['maptype']); unset($items['maplat']); unset($items['maplon']); unset($items['mapzoom']); unset($items['maptype']); break; case 'validate': break; case 'submit': break; case 'view': if (count($items[0]) || $field['widget']['always_display']) { include_once(drupal_get_path('module', 'cck_map') .'/cck_map.inc'); //use cck_map_nummaps on output to avoid namespace colisions static $cck_map_nummaps =0 ; static $maps_js_added = false; //ensure that the google maps javascrip is only added once if (!$maps_js_added) { drupal_set_html_head("" ); $maps_js_added = true; } $prefix = str_replace("_", "-", $field['field_name']) . $cck_map_nummaps; $js_prefix = str_replace("-", "_", $field['field_name']) . $cck_map_nummaps; drupal_add_js(drupal_get_path('module', 'cck_map') .'/cck_map.js'); //create the markers for this map. //print_r($items); cck_map_create_markers_js($items, $js_prefix); $items['maplat'] ? $lat = $items['maplat'] : $lat = 0; $items['maplon'] ? $lon = $items['maplon'] : $lon = 0; $items['mapzoom'] ? $zoom = $items['mapzoom'] : $zoom = 0; $items['maptype'] ? $maptype = $items['maptype'] : $maptype = ''; //google maps doesn't like relative urls for marker images. This totally sucks and I hope to fix it. I appologize. //$tld = $_SERVER['SERVER_NAME']; $tld = $_SERVER['SERVER_NAME']; drupal_add_js("\$(document).ready(function () {var {$js_prefix}map;{$js_prefix}map = new gmapClientController('{$prefix}',". $lat .", ". $lon .", ". $zoom .", '". $maptype ."', {$js_prefix}markers, '". $tld ."'); } );", 'inline'); $theme = theme('cck_map', $node, $field, $items, $teaser, $page, $prefix); $cck_map_nummaps++; return $theme; } break; case 'load': if ($node->nid) { $map_info = db_fetch_array(db_query("SELECT maplat, maplon, mapzoom, maptype from {cck_map} WHERE nid = %d and vid = %d", $node->nid, $node->vid)); if (is_array($map_info)) { return array($field['field_name'] => array_merge($node->$field['field_name'], $map_info)); } } else { return array($field['field_name'] => array_merge($node->$field['field_name'], array('maplat' => 0, 'maplon' => 0, 'mapzoom' => 0, 'maptype' => ''))); } break; } } /** * Declare information about a formatter. * * @return * An array keyed by formatter name. Each element of the array is an associative * array with these keys and values: * - "label": The human-readable label for the formatter. * - "field types": An array of field type names that can be displayed using * this formatter. */ function cck_map_field_formatter_info() { return array( 'map_location' => array( 'label' => 'Default map output', 'field types' => array('map_location'), ), ); } /** * Prepare an individual item for viewing in a browser. * * @param $field * The field the action is being performed on. * @param $item * An array, keyed by column, of the data stored for this item in this field. * @param $formatter * The name of the formatter being used to display the field. * @param $node * The node object, for context. Will be NULL in some cases. * Warning : when displaying field retrieved by Views, $node will not * be a "full-fledged" node object, but an object containg the data returned * by the Views query (at least nid, vid, changed) * @return * An HTML string containing the formatted item. * * In a multiple-value field scenario, this function will be called once per * value currently stored in the field. This function is also used as the handler * for viewing a field in a views.module tabular listing. * * It is important that this function at the minimum perform security * transformations such as running check_plain() or check_markup(). */ function cck_map_field_formatter($field, $item, $formatter, $node) { return false; } /** * Declare information about a widget. * * @return * An array keyed by widget name. Each element of the array is an associative * array with these keys and values: * - "label": The human-readable label for the widget. * - "field types": An array of field type names that can be edited using * this widget. */ function cck_map_widget_info() { return array( 'map_location' => array( 'label' => 'Map Location', 'field types' => array('map_location'), ), ); } /** * Handle the parameters for a widget. * * @param $op * The operation to be performed. Possible values: * - "form": Display the widget settings form. * - "validate": Check the widget settings form for errors. * - "save": Declare which pieces of information to save back to the database. * @param $widget * The widget on which the operation is to be performed. * @return * This varies depending on the operation. * - The "form" operation should return an array of form elements to add to * the settings page. * - The "validate" operation has no return value. Use form_set_error(). * - The "save" operation should return an array of names of form elements to * be saved in the database. */ function cck_map_widget_settings($op, $widget) { switch ($op) { case 'form': $form = array(); $key = variable_get('cck_map_key', 0); if (!$key) { $form['alert'] = array( '#value' => "
You must first get a google maps api key and enter it into the CCK Map settings located ". l('here', 'admin/settings/cck_map') ."
", '#weight' => -50, ); } $form['use_image'] = array( '#type' => 'checkbox', '#title' => t('Use Custom Map Markers'), '#default_value' => isset($widget['use_image']) ? $widget['use_image'] : 1 ); $form['use_title'] = array( '#type' => 'checkbox', '#title' => t('Allow Marker Titles.'), '#default_value' => isset($widget['use_title']) ? $widget['use_title'] : 1 ); $form['use_description'] = array( '#type' => 'checkbox', '#title' => t('Allow Marker Descriptions.'), '#default_value' => isset($widget['use_description']) ? $widget['use_description'] : 1 ); $form['mapx'] = array( '#type' => 'textfield', '#title' => t('Map output width'), '#default_value' => isset($widget['mapx']) ? $widget['mapx'] : 400, '#description' => 'The width(in pixels) that the map is displayed to end users' ); $form['mapy'] = array( '#type' => 'textfield', '#title' => t('Map output height'), '#default_value' => isset($widget['mapy']) ? $widget['mapy'] : 300, '#description' => 'The height(in pixels) that the map is displayed to end users' ); $form['always_display'] = array( '#type' => 'checkbox', '#title' => t('Display map even if no markers have been placed?'), '#default_value' => isset($widget['always_display']) ? $widget['always_display'] : 0, '#description' => 'When selected the map will always display, regardless of whether you have placed any markers' ); return $form; break; case 'validate': if (!is_numeric($widget['mapx'])) form_set_error('mapx', 'map width value must be numeric'); if (!is_numeric($widget['mapy'])) form_set_error('mapy', 'map height must be numeric'); break; case 'save': return array('use_title', 'use_description', 'use_image', 'mapx', 'mapy', 'always_display'); case 'callbacks': return array( 'default value' => CONTENT_CALLBACK_DEFAULT, ); } } /** * Define the behavior of a widget. */ function cck_map_widget($op, &$node, $field, &$items) { switch ($op) { case 'form': static $maps_js_added = false; //ensure that the google maps javascrip is only added once if (!$maps_js_added) { drupal_set_html_head("" ); $maps_js_added = true; } $prefix = str_replace("_", "-", $field['field_name']); drupal_add_css(drupal_get_path('module', 'cck_map') .'/map-edit.css'); drupal_add_js(drupal_get_path('module', 'cck_map') .'/cck_map.js'); $form = array(); $form = _cck_map_get_control_fields($field, $items); //make sure all point elements are within a span, so javascript can more easily target them for editing/deletion. $points_delta = 99; $form[$field['field_name']]['points_open'] = array( '#value' => '', '#weight' => $points_delta -1 ); if ($_POST[$field['field_name']]) { if ($_POST[$field['field_name']]['itemcount'] > 0) { $items = $_POST[$field['field_name']]; foreach ($items as $delta => $values) { //filter out non-database control and helper fields if (is_numeric($delta)) { _cck_map_create_point_widget($form[$field['field_name']][$delta], $field, $values, $points_delta .".". $delta); } } } } else { foreach ($items as $delta => $values) { if (is_numeric($delta)) { _cck_map_create_point_widget($form[$field['field_name']][$delta], $field, $values, $points_delta .".". $delta); } } } $form[$field['field_name']]['points_close'] = array( '#value' => '', '#weight' => $points_delta + 1 ); //number of items is always 4 less than the count, due to associate map view fields $form[$field['field_name']]['itemcount'] = array('#type' => 'hidden', '#value' => count($items)-4 ); return $form; break; case 'validate': //gotta be careful here, 0 is a valid value for both lat or lon if ($field['required'] && (!is_numeric($items[0]['lat'])|| !is_numeric($items[0]['lon']))) form_set_error($field['field_name'], $field['widget']['label'] ." requires you to place at least one marker."); foreach ($items as $delta => $values) { //filter out non numeric map view information if (is_numeric($delta)) if (!is_numeric($values['lat']) || !is_numeric($values['lon'])) unset($items[$delta]); } break; case 'process form values': unset($items['markerTitle']); unset($items['markerImage']); unset($items['markerDescription']); unset($items['itemcount']); break; } } function _cck_map_create_point_widget(&$form, $field, $value, $delta) { $form['#weight'] = $delta; $form['lat'] = array('#type' => 'hidden', '#default_value' => $value['lat']); $form['lon'] = array('#type' => 'hidden', '#default_value' => $value['lon']); if ($field['widget']['use_title']) $form['title'] = array('#type' => 'hidden', '#default_value' => $value['title']); if ($field['widget']['use_description']) $form['description'] = array('#type' => 'hidden', '#default_value' => $value['description']); if ($field['widget']['use_image']) $form['image'] = array('#type' => 'hidden', '#default_value' => $value['image'] ); } /* * Returns the map and some addition fields used by the javascript to add/edit markers, as well as fields about the map view which are saved outside of CCK. */ function _cck_map_get_control_fields($field, $items) { $form = array(); $prefix = str_replace("_", "-", $field['field_name']); //js obviously dislikes '-' characters in variable names. $js_prefix = str_replace("-", "_", $field['field_name']); $form[$field['field_name']] = array( '#type' => 'fieldset', '#title' => $field['widget']['label'], '#collapsible' => true, '#collapsed' => false, '#weight' => $field['widget']['weight'], '#attributes' => array('class' => 'cck-location-map-fieldset'), '#tree' => true ); $form[$field['field_name']]['map'] = array( "#value" => "", '#prefix' => $field['widget']['description'] ? "". $field['widget']['description'] ."
" : '', '#weight' => -15 ); if ($field['widget']['use_title'] || $field['widget']['use_description'] || $field['widget']['use_image']) { $form[$field['field_name']]['groupingOpen'] = array('#value' => "