Advertisement
Guest User

Untitled

a guest
Mar 7th, 2011
354
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 18.26 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4.  * @file
  5.  * Defines location field type.
  6.  */
  7.  
  8. /**
  9.  * Implements hook_theme().
  10.  */
  11. function location_cck_theme() {
  12.   return array(
  13.     'location_cck_field_all' => array(
  14.       'variables' => array(
  15.         'location' => NULL,
  16.         'hide' => array(),
  17.         'field' => NULL,
  18.         'instance' => NULL,
  19.       ),
  20.     ),
  21.     'location_cck_field_map' => array(
  22.       'variables' => array(
  23.         'locations' => NULL,
  24.         'field' => NULL,
  25.         'instance' => NULL,
  26.       ),
  27.     ),
  28.     'location_cck_field_popup' => array(
  29.       'variables' => array(
  30.         'location' => NULL,
  31.         'instance' => NULL,
  32.       ),
  33.     ),
  34.   );
  35. }
  36.  
  37. /**
  38.  * Implements hook_field_info().
  39.  */
  40. function location_cck_field_info() {
  41.   return array(
  42.     'location' => array(
  43.       'label' => t('Location'),
  44.       'description' => t('Store a location.module location.'),
  45.       'settings' => array(),
  46.       'instance_settings' => array(),
  47.       'default_widget' => 'location',
  48.       'default_formatter' => 'location_default',
  49.     ),
  50.   );
  51. }
  52.  
  53. /**
  54.  * Implement hook_field_settings_form().
  55.  */
  56. function location_cck_field_settings_form($field, $instance, $has_data) {
  57.   $settings = isset($field['settings']['location_settings']) ? $field['settings']['location_settings'] : array();
  58.   $form = array();
  59.   $form['location_settings'] = location_settings($settings);
  60.  
  61.   // Multiple is handled by CCK.
  62.   unset($form['location_settings']['multiple']);
  63.   // CCK handles weight, and collapsibility is not changeable.
  64.   unset($form['location_settings']['form']['weight']);
  65.   unset($form['location_settings']['form']['collapsible']);
  66.   unset($form['location_settings']['form']['collapsed']);
  67.   unset($form['location_settings']['display']['weight']);
  68.  
  69.   // We want to see the settings, so uncollapse them.
  70.   $form['location_settings']['#collapsible'] = FALSE;
  71.   $form['location_settings']['form']['#collapsed'] = FALSE;
  72.   $form['location_settings']['display']['#collapsed'] = FALSE;
  73.  
  74.   // Add some GMap settings, if GMap is enabled.
  75.   if (module_exists('gmap')) {
  76.     $form['gmap_macro'] = array(
  77.       '#type' => 'textarea',
  78.       '#title' => t('GMap Macro'),
  79.       '#rows' => 2,
  80.       '#maxlength' => 500,
  81.       '#description' => t('A macro to be used as a base map for this field.  This map will be recentered on the location, so the center is not that important.'),
  82.       '#default_value' => !empty($field['settings']['gmap_macro']) ? $field['settings']['gmap_macro'] : '[gmap ]',
  83.     );
  84.     $options = gmap_get_marker_titles();
  85.     $form['gmap_marker'] = array(
  86.       '#type' => 'select',
  87.       '#title' => t('GMap marker'),
  88.       '#options' => $options,
  89.       '#default_value' => !empty($field['settings']['gmap_marker']) ? $field['settings']['gmap_marker'] : 'drupal',
  90.     );
  91.   }
  92.   else {
  93.     // Preserve existing data, apply defaults even if gmap is disabled.
  94.     $form['gmap_macro'] = array(
  95.       '#type' => 'value',
  96.       '#value' => !empty($field['settings']['gmap_macro']) ? $field['settings']['gmap_macro'] : '[gmap ]',
  97.     );
  98.     $form['gmap_marker'] = array(
  99.       '#type' => 'value',
  100.       '#value' => !empty($field['settings']['gmap_marker']) ? $field['settings']['gmap_marker'] : 'drupal',
  101.     );
  102.   }
  103.  
  104.   return $form;
  105. }
  106.  
  107. /**
  108.  * Implements hook_field_settings().
  109.  */
  110. function location_cck_field_settings($op, $field) {
  111.   switch ($op) {
  112.     case 'views data':
  113.       // We want to for the most part use the CCK stuff, but we also want to
  114.       // patch in a relationship so location's views support can target
  115.       // cck fields directly.
  116.       $table = content_views_tablename($field);
  117.       $db_info = content_database_info($field);
  118.       $field_alias = $db_info['columns']['lid']['column'];
  119.       $data = content_views_field_views_data($field);
  120.       $data[$table][$field_alias]['relationship'] = array(
  121.         'base' => 'location',
  122.         'field' => 'lid',
  123.         'handler' => 'views_handler_relationship',
  124.         'label' => t('Location'), // @@@ Some sort of better name?
  125.       );
  126.       return $data;
  127.   }
  128. }
  129.  
  130. /**
  131.  * Implement hook_field_schema().
  132.  */
  133. function location_cck_field_schema($field) {
  134.   switch ($field['type']) {
  135.     case 'location':
  136.       $columns = array(
  137.         'lid' => array(
  138.           'type' => 'int',
  139.           'unsigned' => TRUE,
  140.           'not null' => FALSE,
  141.         ),
  142.       );
  143.       break;
  144.   }
  145.   return array(
  146.     'columns' => $columns,
  147.     'indexes' => array('lid' => array('lid')),
  148.   );
  149. }
  150.  
  151. /**
  152.  * Implement hook_field_insert().
  153.  */
  154. function location_cck_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
  155.   $criteria = array();
  156.   if ($entity_type == 'node') {
  157.     // Store instances of locations by field name and vid.
  158.     $criteria = array(
  159.       'genid' => 'cck:' . $field['field_name'] . ':' . $entity->vid,
  160.       'vid' => $entity->vid,
  161.       'nid' => $entity->nid,
  162.     );
  163.   }else if($entity_type == 'user'){
  164.     $criteria = array('uid'=>$entity->uid);
  165.   }
  166. }
  167.  
  168. /**
  169.  * Implement hook_field_update().
  170.  */
  171. function location_cck_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
  172.    $criteria = array();
  173.   if ($entity_type == 'node') {
  174.     // Store instances of locations by field name and vid.
  175.     $criteria = array(
  176.       'genid' => 'cck:' . $field['field_name'] . ':' . $entity->vid,
  177.       'vid' => $entity->vid,
  178.       'nid' => $entity->nid,
  179.     );
  180.    }else if($entity_type == 'user'){
  181.      $criteria = array('uid'=>$entity->uid);
  182.   }
  183.   location_save_locations($items, $criteria);
  184. }
  185.  
  186. /**
  187.  * Implement hook_field_delete().
  188.  */
  189. function location_cck_field_delete($entity_type, $entity, $field, $instance, $langcode, &$items) {
  190.   if ($entity_type == 'node') {
  191.     // @TODO: Fix this properly.
  192.  
  193.     // Use the CCK storage to figure out the vids that need to be deleted,
  194.     // and clean up all the applicable references.
  195.    // $db_info = content_database_info($field);
  196.   //  $result = db_query('SELECT vid FROM {' . $db_info['table'] . '} WHERE nid = :nid', array(':nid' => $node->nid));
  197.     $result = db_query('SELECT vid FROM {node_revision} WHERE nid = :nid', array(':nid' => $entity->nid));
  198.     foreach ($result as $row) {
  199.       $genid = 'cck:' . $field['field_name'] . ':' . $row->vid;
  200.       $locs = array();
  201.       location_save_locations($locs, array('genid' => $genid));
  202.     }
  203.   }
  204. }
  205.  
  206. /**
  207.  * Implement hook_field_delete_revision().
  208.  */
  209. function location_cck_field_delete_revision($entity_type, $entity, $field, $instance, $langcode, &$items) {
  210.   if ($entity_type == 'node') {
  211.     $genid = 'cck:' . $field['field_name'] . ':' . $entity->vid;
  212.     $locs = array();
  213.     location_save_locations($locs, array('genid' => $genid));
  214.   }
  215. }
  216.  
  217. /**
  218.  * Implement hook_field_validate().
  219.  */
  220. function location_cck_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
  221.   // @@@ Fixme
  222. }
  223.  
  224. /**
  225.  * Implement hook_field_load().
  226.  */
  227. function location_cck_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
  228.   if ($entity_type == 'node') {
  229.     foreach ($entities as $id => $entity) {
  230.       foreach ($items[$id] as $delta => $item) {
  231.         $location = array();
  232.         // Load the location if it exists.
  233.         // If we are previewing a new node it will not.
  234.         if (!empty($item['lid'])) {
  235.           $location = location_load_location($item['lid']);
  236.         }
  237.         // Combine the item with the location loaded from the database.
  238.         // This will allow $item to display in the case of previewing a node.
  239.         $items[$id][$delta] = array_merge($location, $item);
  240.       }
  241.     }
  242.   }
  243. }
  244.  
  245. /**
  246.  * Implements hook_field().
  247.  */
  248. function location_cck_field($op, &$node, $field, &$items, $teaser, $page) {
  249.   switch ($op) {
  250.     case 'sanitize':
  251.       // Get the location information for the lid if it hasn't already been
  252.       // loaded (in the hook_field() load $op using location_load_location()).
  253.       // This is necessary for Views and any other modules that use the
  254.       // content_format() function to render CCK fields because content_format()
  255.       // doesn't call the "load" $op.
  256.       foreach ($items as $delta => $item) {
  257.         if (!isset($item['latitude'])) {
  258.           $items[$delta] = array_merge($items[$delta], location_load_location($item['lid']));
  259.         }
  260.       }
  261.       break;
  262.   }
  263. }
  264.  
  265. /**
  266.  * Implementation of hook_field_formatter_info().
  267.  */
  268. function location_cck_field_formatter_info() {
  269.   $info = array(
  270.     'location_default' => array(
  271.       'label' => t('Default (address)'),
  272.       'field types' => array('location'),
  273.     ),
  274.   );
  275.   if (module_exists('gmap')) {
  276.     $info['location_all'] = array(
  277.       'label' => t('Address with map'),
  278.       'field types' => array('location'),
  279.     );
  280.     $info['location_map'] = array(
  281.       'label' => t('Map only'),
  282.       'field types' => array('location'),
  283.     );
  284.     // @@@ How to do in D7?
  285.     $info['location_multiple'] = array(
  286.       'label' => t('Multiple field values on a single map'),
  287.       'field types' => array('location'),
  288.     );
  289.   }
  290.   return $info;
  291. }
  292.  
  293. /**
  294.  * Implements hook_field_formatter_view().
  295.  * @Todo: This.
  296.  */
  297. function location_cck_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  298.   $element = array();
  299.  
  300.   $settings = $field['settings']['location_settings'];
  301.   $hide = (isset($settings['display']['hide'])) ? array_keys(array_filter($settings['display']['hide'])) : array();
  302.  
  303.   switch ($display['type']) {
  304.     case 'location_default':
  305.       foreach ($items as $delta => $item) {
  306.         if (!empty($item['lid']) || !empty($entity->in_preview)) {
  307.           $element[$delta]['#theme'] = 'location';
  308.           $element[$delta]['#location'] = $item;
  309.           $element[$delta]['#hide'] = $hide;
  310.         }
  311.       }
  312.       break;
  313.  
  314.     case 'location_all':
  315.       foreach ($items as $delta => $item) {
  316.         if (!empty($item['lid']) || !empty($entity->in_preview)) {
  317.           $element[$delta]['#theme'] = 'location_cck_field_all';
  318.           $element[$delta]['#location'] = $item;
  319.           $element[$delta]['#hide'] = $hide;
  320.           $element[$delta]['#field'] = $field;
  321.           $element[$delta]['#instance'] = $instance;
  322.         }
  323.       }
  324.       break;
  325.  
  326.     case 'location_map':
  327.       foreach ($items as $delta => $item) {
  328.         if (!empty($item['lid']) || !empty($entity->in_preview)) {
  329.           $element[$delta]['#theme'] = 'location_cck_field_map';
  330.           $element[$delta]['#locations'] = array($item);
  331.           $element[$delta]['#field'] = $field;
  332.           $element[$delta]['#instance'] = $instance;
  333.         }
  334.       }
  335.       break;
  336.  
  337.     case 'location_multiple':
  338.       $element[0]['#theme'] = 'location_cck_field_map';
  339.       $element[0]['#locations'] = $items;
  340.       $element[0]['#field'] = $field;
  341.       $element[0]['#instance'] = $instance;
  342.       break;
  343.   }
  344.  
  345.   return $element;
  346. }
  347.  
  348. /**
  349.  * Implements hook_field_widget_info().
  350.  */
  351. function location_cck_field_widget_info() {
  352.   return array(
  353.     'location' => array(
  354.       'label' => t('Location Field'),
  355.       'field types' => array('location'),
  356.     ),
  357.   );
  358. }
  359.  
  360. /**
  361.  * Implement hook_field_widget_form().
  362.  */
  363. function location_cck_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  364.   if ($field['type'] == 'location') {
  365.     $settings = $field['settings']['location_settings'];
  366.  
  367.     // Load location data for existing locations.
  368.     if (isset($items[$delta]['lid']) && $items[$delta]['lid']) {
  369.       $location = location_load_location($items[$delta]['lid']);
  370.     }
  371.     // Load location data passed by cck.
  372.     else if (isset($items[$delta]) && is_array($items[$delta]) && !empty($items[$delta])) {
  373.  
  374.       // Initialize empty location.
  375.       $location = location_empty_location($settings);
  376.       foreach ($items[$delta] as $k => $v) {
  377.         $location[$k] = $v;
  378.       }
  379.       // We can't trust that CCK is giving us the right information.
  380.       // It can't tell us whether $items is defaults or multistep values.
  381.       // Location *needs* the defaults to match the initial field values,
  382.       // so we re-calculate the defaults here and stash them into the settings.
  383.       // @@@ There is still a bug here!
  384.       // If you go back and edit something, and you hadn't set a location the
  385.       // first time, CCK fails to set up the defaults properly!
  386.       // I'm just going to leave it like that for now, because I don't know how
  387.       // to work around it.
  388.       $temp = NULL; //content_default_value($form, $form_state, $field, 0);
  389.       if (is_array($temp) && isset($temp[$delta]) && is_array($temp[$delta])) {
  390.         foreach ($temp[$delta] as $k => $v) {
  391.           $settings['form']['fields'][$k]['default'] = $v;
  392.         }
  393.       }
  394. //      unset($location['location_settings']);
  395. //      unset($location['locpick']);
  396.     }
  397.     else {
  398.       $location = location_empty_location($settings);
  399.     }
  400.  
  401.     $element = array(
  402.       '#type' => 'location_element',
  403.       '#title' => t($instance['label']),
  404.       '#description' => t($instance['description']),
  405.       '#required' => $instance['required'],
  406.       '#location_settings' => $settings,
  407.       '#default_value' => $location,
  408.     );
  409.  
  410.     return $element;
  411.   }
  412. }
  413.  
  414. /**
  415.  * Implements hook_field_is_empty().
  416.  */
  417. function location_cck_field_is_empty($item, $field) {
  418.   $fields = array();
  419.   if (location_is_empty($item, $fields)) {
  420.     return TRUE;
  421.   }
  422.   return FALSE;
  423. }
  424.  
  425. /**
  426.  * Return both an address and a map for an individual item.
  427.  */
  428. function theme_location_cck_field_all($variables) {
  429.   $content = theme('location', array('location' => $variables['location'], 'hide' => $variables['hide']));
  430.   $content .= theme_location_cck_field_map(array('locations' => array($variables['location']), 'field' => $variables['field'], 'instance' => $variables['instance']));
  431.   return $content;
  432. }
  433.  
  434. /**
  435.  * Alternate function to return a map with all
  436.  * multiple values in the same map.
  437.  */
  438. function theme_location_cck_formatter_combined($variables) {
  439.   $location = $variables['element'];
  440.  
  441.   $field = content_fields($element['#field_name'], $element['#type_name']);
  442.   $locations = $element['#items'];
  443.   return theme_location_cck_field_map(array('locations' => $locations, 'field' => $field));
  444. }
  445.  
  446. /**
  447.  * Generate a GMap map for one or more location field values.
  448.  *
  449.  * Mostly just cut and paste from gmap_location
  450.  * block view.
  451.  */
  452. function theme_location_cck_field_map($variables) {
  453.   $locations = $variables['locations'];
  454.   $field = $variables['field'];
  455.   $instance = $variables['instance'];
  456.  
  457.   $count = 0;
  458.   $content = '';
  459.   foreach ($locations as $location) {
  460.     if (location_has_coordinates($location)) {
  461.       $count++;
  462.       $markername = isset($field['settings']['gmap_marker']) ? $field['settings']['gmap_marker'] : 'drupal';
  463.       $markers[] = array(
  464.         'latitude' => $location['latitude'],
  465.         'longitude' => $location['longitude'],
  466.         'markername' => $markername,
  467.         'offset' => $count-1,
  468.         'text' => theme('location_cck_field_popup', array('location' => $location, 'instance' => $instance)),
  469.       );
  470.     }
  471.   }
  472.   if (!empty($markers)) {
  473.     $macro = !empty($field['settings']['gmap_macro']) ? $field['settings']['gmap_macro'] : '[gmap ]';
  474.     $map = array_merge(gmap_defaults(), gmap_parse_macro($macro));
  475.     $map['latitude'] = $markers[0]['latitude'];
  476.     $map['longitude'] = $markers[0]['longitude'];
  477.     $map['markers'] = $markers;
  478.     $map['id'] = gmap_get_auto_mapid();
  479.     $content = theme('gmap', array('element' => array('#gmap_settings' => $map)));
  480.   }
  481.  
  482.   return $content;
  483. }
  484.  
  485. /**
  486.  * Theme the GMap popup text for the field.
  487.  */
  488. function theme_location_cck_field_popup($variables) {
  489.   $location = $variables['location'];
  490.   $instance = $variables['instance'];
  491.  
  492.   $hide = (isset($field['location_settings']['display']['hide'])) ? array_keys(array_filter($field['location_settings']['display']['hide'])) : array();
  493.   // Don't use a map link in a popup!
  494.   // We're making the name into a title.
  495.   $hide[] = 'map_link';
  496.   $hide[] = 'name';
  497.  
  498.   $markertitle = $instance['label'];
  499.   if (!empty($location['name'])) {
  500.     $markertitle = $location['name'];
  501.   }
  502.   return '<h4>'. $markertitle .'</h4>'. theme('location', array('location' => $location, 'hide' => $hide));
  503. }
  504.  
  505. /**
  506.  * Implements hook_token_list().
  507.  */
  508. function location_cck_token_list($type = 'all') {
  509.   if ($type == 'field') {
  510.     $tokens = array();
  511.  
  512.     $fields = location_field_names(TRUE);
  513.     // @@@ We really need to rethink fields in location..
  514.     unset($fields['locpick']);
  515.     foreach ($fields as $k => $v) {
  516.       $tokens['location'][$k] = $v;
  517.     }
  518.  
  519.     return $tokens;
  520.   }
  521. }
  522.  
  523. /**
  524.  * Implements hook_token_values().
  525.  */
  526. function location_cck_token_values($type, $object = NULL) {
  527.   if ($type == 'field') {
  528.     $tokens = array();
  529.     $item = $object[0];
  530.     if ($item['lid']) {
  531.       // If the location exists, we need to set up the tokens.
  532.  
  533.       $location = array(
  534.         // There is no way to find out which elements to hide because $item does not contain
  535.         // the 'location_settings' element, so for now, just set it to be an empty array.
  536.         // See http://drupal.org/node/463618 for more infomation.
  537.         'hide' => array(),
  538.         'location' => location_load_location($item['lid']),
  539.       );
  540.  
  541.       // @@@ This is rather silly, but I can't think of anything better at the moment.
  542.       $variables = array('location' => $location);
  543.       template_preprocess_location($variables);
  544.  
  545.       $fields = location_field_names(TRUE);
  546.       // @@@ We really need to rethink fields in location..
  547.       unset($fields['locpick']);
  548.       foreach ($fields as $k => $v) {
  549.         if (isset($location[$k])) {
  550.           $tokens[$k] = $location[$k];
  551.         }
  552.         else {
  553.           $tokens[$k] = '';
  554.         }
  555.       }
  556.     }
  557.     return $tokens;
  558.   }
  559. }
  560.  
  561. /**
  562.  * Implements hook_locationapi().
  563.  */
  564. function location_cck_locationapi(&$obj, $op, $a3 = NULL, $a4 = NULL, $a5 = NULL) {
  565.   switch ($op) {
  566.     case 'instance_links':
  567.       foreach ($obj as $k => $v) {
  568.         if (substr($v['genid'], 0, 4) == 'cck:') {
  569.           $data = explode(':', $v['genid']);
  570.           $obj[$k]['href'] = 'node/' . $data[2];
  571.           $obj[$k]['title'] = t('CCK location');
  572.           $obj[$k]['type'] = t('CCK location');
  573.         }
  574.       }
  575.   }
  576. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement