diff --git a/drush/openlayers_proximity.drush.inc b/drush/openlayers_proximity.drush.inc index 9fe6e6d..29d3b4d 100644 --- a/drush/openlayers_proximity.drush.inc +++ b/drush/openlayers_proximity.drush.inc @@ -12,12 +12,10 @@ function openlayers_proximity_drush_command() { $items['rebuild-proximity'] = array( 'description' => 'Rebuild OpenLayers Proximity index.', -// 'options' => array( -// 'nodes' => 'Comma delimited list nodes NID.', -// ), + // 'options' => array( // 'nodes' => 'Comma delimited list nodes NID.', // ), 'examples' => array( 'drush rebuild-proximity' => 'Rebuild proximity index for all nodes.', -// 'drush rebuild-proximity --nodes=1,2,3' => 'Rebuild proximity index for nodes 1, 2 and 3.', + // 'drush rebuild-proximity --nodes=1,2,3' => 'Rebuild proximity index for nodes 1, 2 and 3.', ), 'aliases' => array('rp'), ); @@ -39,17 +37,17 @@ function openlayers_proximity_drush_help($section) { * Implements drush_hook_COMMAND_validate(). */ function drush_openlayers_proximity_rebuild_proximity() { - + // $nodes = drush_get_option('nodes'); $batch = array( 'title' => dt('Rebuild proximity index'), 'operations' => array(array('openlayers_proximity_rebuild_index', array())), 'finished' => 'openlayers_proximity_rebuild_index_finished', - 'init_message' => dt('The proximity index rebuilding process is beginning.'), + 'init_message' => dt('The proximity index rebuilding process is beginning.'), 'progress_message' => dt('Index rebuilt for @current out of @total.'), 'error_message' => dt('The proximity index rebuilding process encountered an error.'), ); - + batch_set($batch); drush_backend_batch_process(); -} \ No newline at end of file +} diff --git a/includes/openlayers_proximity.rules.inc b/includes/openlayers_proximity.rules.inc index 74cdcb0..6f85879 100644 --- a/includes/openlayers_proximity.rules.inc +++ b/includes/openlayers_proximity.rules.inc @@ -1,24 +1,31 @@ - array( 'label' => t('Node is notified based on geographic proximity'), 'module' => 'OpenLayers Proximity', 'arguments' => array( - 'nodeA' => array('type' => 'node', 'label' => t('First node, which notifies the second.')), - 'nodeB' => array('type' => 'node', 'label' => t('Second node, which is notified by the first.')), + 'nodeA' => array( + 'type' => 'node', + 'label' => t('First node, which notifies the second.'), + ), + 'nodeB' => array( + 'type' => 'node', + 'label' => t('Second node, which is notified by the first.'), + ), ), ), ); } /** - * Implementation of hook_rules_action_info(). + * Implements hook_rules_action_info(). * @ingroup rules */ function openlayers_proximity_rules_action_info() { @@ -26,7 +33,10 @@ function openlayers_proximity_rules_action_info() { 'openlayers_proximity_action_notify_nodes' => array( 'label' => t('Notify nodes based on geographic proximity'), 'arguments' => array( - 'node' => array('type' => 'node', 'label' => t('Content with locaiton')), + 'node' => array( + 'type' => 'node', + 'label' => t('Content with locaiton'), + ), ), 'module' => 'OpenLayers Proximity', ), @@ -37,22 +47,22 @@ function openlayers_proximity_rules_action_info() { * Implementation of action callback. */ function openlayers_proximity_action_notify_nodes($nodeA, $settings) { - list($view, $display_id, $filter_id) = explode('-', $settings['display']); - - if ($view = views_get_view($view)) { - $view->build($display_id); - $filter = $view->display_handler->get_handler('filter', $filter_id); - $filter->options['location_as'] = 'node'; - $filter->value['node'] = $nodeA->nid; - $view->display_handler->execute(); - - if ($view->result) { - foreach ($view->result as $row) { - $nodeB = node_load((int) $row->nid); - rules_invoke_event('proximity_notification', $nodeA, $nodeB); - } - } - } + list($view, $display_id, $filter_id) = explode('-', $settings['display']); + + if ($view = views_get_view($view)) { + $view->build($display_id); + $filter = $view->display_handler->get_handler('filter', $filter_id); + $filter->options['location_as'] = 'node'; + $filter->value['node'] = $nodeA->nid; + $view->display_handler->execute(); + + if ($view->result) { + foreach ($view->result as $row) { + $nodeB = node_load((int) $row->nid); + rules_invoke_event('proximity_notification', $nodeA, $nodeB); + } + } + } } /** @@ -60,7 +70,10 @@ function openlayers_proximity_action_notify_nodes($nodeA, $settings) { */ function openlayers_proximity_action_notify_nodes_form($settings, &$form) { - $settings += array('message' => '', 'error' => ''); + $settings += array( + 'message' => '', + 'error' => '', + ); $options = array(); if ($views = views_get_all_views()) { foreach ($views as $view) { @@ -69,18 +82,18 @@ function openlayers_proximity_action_notify_nodes_form($settings, &$form) { $view->build($display_id); foreach ($view->display_handler->get_handlers('filter') as $filter_id => $handler) { if ($handler->definition['handler'] == 'openlayers_proximity_handler_filter_circle' || $handler->definition['handler'] == 'openlayers_proximity_handler_filter_square') { - $options[$view->name][$view->name .'-'. $display_id .'-'. $filter_id] = t('@display - @filter (@filter_id)', array('@display' => $display->display_title, '@filter' => $handler->definition['title'] .' '. $handler->admin_summary(), '@filter_id' => $filter_id)); + $options[$view->name][$view->name . '-' . $display_id . '-' . $filter_id] = t('@display - @filter (@filter_id)', array('@display' => $display->display_title, '@filter' => $handler->definition['title'] . ' ' . $handler->admin_summary(), '@filter_id' => $filter_id)); } - } + } } } } } - + if (count($options) == 0) { - drupal_set_message(t('In order to proceed you need to create at least one Views display using a proximity filter: it will be used to filter out which nodes will be notified when this action will be performed.', array('!url' => url('admin/build/views/add'))), 'warning'); + drupal_set_message(t('In order to proceed you need to create at least one Views display using a proximity filter: it will be used to filter out which nodes will be notified when this action will be performed.', array('!url' => url('admin/structure/views/add'))), 'warning'); } - + $form['settings']['display'] = array( '#type' => 'select', '#title' => t('Views display'), @@ -88,6 +101,6 @@ function openlayers_proximity_action_notify_nodes_form($settings, &$form) { '#options' => $options, '#required' => TRUE, '#description' => t('Choose which Views display will be in charge of retrieving the nodes that needs to be notified. The starting point node will be passed to the specified proximity filter.'), - ); + ); } diff --git a/openlayers_proximity.info b/openlayers_proximity.info index b1a5525..53554a2 100644 --- a/openlayers_proximity.info +++ b/openlayers_proximity.info @@ -1,6 +1,20 @@ name = OpenLayers Proximity description = Geographical proximity search for the OpenLayers module. -core = 6.x +core = 7.x package = OpenLayers dependencies[] = openlayers + +; Information added by drupal.org packaging script on 2011-02-25 +version = "7.x-2.x-dev" +core = 7.x +project = "openlayers_proximity" +datestamp = "1298619834" + + +files[] = tests/openlayers_proximity.test +files[] = views/openlayers_proximity_handler_field.inc +files[] = views/openlayers_proximity_handler_filter.inc +files[] = views/openlayers_proximity_handler_filter_circle.inc +files[] = views/openlayers_proximity_handler_filter_square.inc +files[] = views/openlayers_proximity_handler_sort.inc diff --git a/openlayers_proximity.install b/openlayers_proximity.install index 8617031..4916ad8 100644 --- a/openlayers_proximity.install +++ b/openlayers_proximity.install @@ -1,14 +1,20 @@ - 'int', 'unsigned' => TRUE, 'not null' => TRUE, - 'default' => 0, + 'default' => 0, 'description' => 'The primary identifier for a node.', ), 'lat' => array( @@ -44,10 +50,9 @@ function openlayers_proximity_schema() { } /** - * Implementation of hook_uninstall(). + * Implements hook_uninstall(). */ function openlayers_proximity_uninstall() { - drupal_uninstall_schema('openlayers_proximity'); } /** @@ -55,8 +60,8 @@ function openlayers_proximity_uninstall() { */ function openlayers_proximity_update_6201() { $return = array(); - db_add_index($return, 'openlayers_proximity', 'nid', array('nid')); - db_add_index($return, 'openlayers_proximity', 'lat', array('lat')); - db_add_index($return, 'openlayers_proximity', 'lon', array('lon')); - return $return; -} \ No newline at end of file + db_add_index('openlayers_proximity', 'nid', array('nid')); + db_add_index('openlayers_proximity', 'lat', array('lat')); + db_add_index('openlayers_proximity', 'lon', array('lon')); + return t('Indexes Added to table: openlayers_proximity.'); +} diff --git a/openlayers_proximity.module b/openlayers_proximity.module index dc64e4f..9dd58bd 100644 --- a/openlayers_proximity.module +++ b/openlayers_proximity.module @@ -1,33 +1,34 @@ - 'Proximity Search', 'page callback' => 'drupal_get_form', 'page arguments' => array('openlayers_proximity_settings'), - 'access arguments' => array('administer openlayers'), + 'access arguments' => array('administer openlayers'), 'type' => MENU_LOCAL_TASK, 'weight' => 10, ); @@ -35,29 +36,53 @@ function openlayers_proximity_menu() { } /** - * Implementation of hook_nodeapi(). + * Implements hook_node_update(). + */ +function openlayers_proximity_node_update($node) { + if (TRUE || TRUE) { + openlayers_proximity_build_node_index($node); + } +} + +/** + * Implements hook_node_insert(). */ -function openlayers_proximity_nodeapi(&$node, $op) { - if ($op == 'update' || $op == 'insert') { +function openlayers_proximity_node_insert($node) { + if (TRUE || TRUE) { openlayers_proximity_build_node_index($node); - } - if ($op == 'delete') { - db_query('DELETE FROM {openlayers_proximity} WHERE nid = %d', $node->nid); - } + } +} + +/** + * Implements hook_node_delete(). + */ +function openlayers_proximity_node_delete($node) { + if (TRUE) { + // TODO Please review the conversion of this statement to the D7 database API syntax. + /* db_query('DELETE FROM {openlayers_proximity} WHERE nid = %d', $node->nid) */ + db_delete('openlayers_proximity') + ->condition('nid', $node->nid) + ->execute(); + } } /** - * Implementation of hook_views_api(). + * Implements hook_nodeapi(). + */ +function openlayers_proximity_nodeapi_OLD(&$node, $op) { } + +/** + * Implements hook_views_api(). */ function openlayers_proximity_views_api() { return array( - 'api' => 2, - 'path' => drupal_get_path('module', 'openlayers_proximity') .'/views', + 'api' => 3, + 'path' => drupal_get_path('module', 'openlayers_proximity') . '/views', ); } /** - * Implementation of hook_views_data() + * Implements hook_views_data(). */ function openlayers_proximity_views_data() { @@ -99,37 +124,9 @@ function openlayers_proximity_views_data() { } /** - * Implementation of hook_views_handlers() - */ -function openlayers_proximity_views_handlers() { - return array( - 'info' => array( - 'path' => drupal_get_path('module', 'openlayers_proximity') .'/views', - ), - 'handlers' => array( - 'openlayers_proximity_handler_filter' => array( - 'parent' => 'views_handler_filter_float', - ), - 'openlayers_proximity_handler_filter_square' => array( - 'parent' => 'openlayers_proximity_handler_filter', - ), - 'openlayers_proximity_handler_filter_circle' => array( - 'parent' => 'openlayers_proximity_handler_filter', - ), - 'openlayers_proximity_handler_sort' => array( - 'parent' => 'views_handler_sort', - ), - 'openlayers_proximity_handler_field' => array( - 'parent' => 'views_handler_field_numeric', - ), - ), - ); -} - -/** * Menu callback. */ -function openlayers_proximity_settings() { +function openlayers_proximity_settings($form, &$form_state) { $form = array(); $form['openlayers_proximity_unit'] = array( @@ -140,16 +137,16 @@ function openlayers_proximity_settings() { '#default_value' => variable_get('openlayers_proximity_unit', OPENLAYERS_PROXIMITY_DEFAULT_UNIT), '#description' => t('Select site wide unit of measurement.'), ); - + $form['rebuild'] = array( - '#type' => 'checkbox', + '#type' => 'checkbox', '#title' => t('Rebuild Index'), '#description' => t('Check and save configuration to rebuild proximity index.'), ); - + $form['#submit'][] = 'openlayers_proximity_settings_submit'; $form = system_settings_form($form); - + return $form; } @@ -158,36 +155,37 @@ function openlayers_proximity_settings() { */ function openlayers_proximity_settings_submit(&$form, &$form_state) { if ($form_state['values']['rebuild']) { - $batch = array( - 'title' => t('Rebuild proximity index'), - 'operations' => array( - array('openlayers_proximity_rebuild_index', array()), - ), - 'finished' => 'openlayers_proximity_rebuild_index_finished', - 'init_message' => t('The proximity index rebuilding process is beginning.'), - 'error_message' => t('The proximity index rebuilding process encountered an error.'), - ); - batch_set($batch); + $batch = array( + 'title' => t('Rebuild proximity index'), + 'operations' => array( + array('openlayers_proximity_rebuild_index', array()), + ), + 'finished' => 'openlayers_proximity_rebuild_index_finished', + 'init_message' => t('The proximity index rebuilding process is beginning.'), + 'error_message' => t('The proximity index rebuilding process encountered an error.'), + ); + batch_set($batch); } unset($form_state['values']['rebuild']); } /** - * Barch API operation callback. + * Batch API operation callback. + * TODO Sort out geofields atached to any entity (as well as 'node') */ function openlayers_proximity_rebuild_index(&$context) { - + if (empty($context['sandbox'])) { $context['sandbox']['progress'] = 0; $context['sandbox']['current_node'] = 0; $context['sandbox']['types'] = module_invoke_all('openlayers_proximity_get_types'); - $context['sandbox']['max'] = db_result(db_query("SELECT COUNT(DISTINCT nid) FROM {node} WHERE type IN (" . db_placeholders($context['sandbox']['types'], 'text') . ")", $context['sandbox']['types'])); + $context['sandbox']['max'] = db_query("SELECT COUNT(DISTINCT nid) FROM {node} WHERE type IN (:types)", array(':types' => $context['sandbox']['types']))->fetchField(); } - $result = db_query_range("SELECT nid FROM {node} WHERE type IN (" . db_placeholders($context['sandbox']['types'], 'text') . ") AND nid > %d ORDER BY nid ASC", $context['sandbox']['types'], $context['sandbox']['current_node'], 0, OPENLAYERS_PROXIMITY_NODES_PER_BATCH); - while ($row = db_fetch_array($result)) { - $node = node_load($row['nid']); + $result = db_query_range("SELECT nid FROM {node} WHERE type IN (:types) AND nid > :cnode ORDER BY nid ASC", 0, OPENLAYERS_PROXIMITY_NODES_PER_BATCH, array(':types' => $context['sandbox']['types'], ':cnode' => $context['sandbox']['current_node']))->fetchAssoc(); + foreach ($result as $nid) { + $node = node_load($nid); $index = openlayers_proximity_build_node_index($node); - $context['results'][] = $node->nid .' : '. $node->title; + $context['results'][] = $node->nid . ' : ' . $node->title; $context['sandbox']['progress']++; $context['sandbox']['current_node'] = $node->nid; $context['message'] = t('Rebuilding proximity index for !type !nid: !title. !count location(s) added.', array('!type' => $node->type, '!nid' => $node->nid, '!title' => $node->title, '!count' => count($index))); @@ -203,18 +201,18 @@ function openlayers_proximity_rebuild_index(&$context) { function openlayers_proximity_rebuild_index_finished($success, $results, $operations) { if ($success) { $message = format_plural(count($results), 'Proximity index rebuilt for 1 node.', 'Proximity index rebuilt for @count nodes.'); - drupal_set_message($message); - } - else { - // A fatal error occurred during batch processing. - $error_operation = reset($operations); - $operation = array_shift($error_operation); - $arguments = array_shift($error_operation); + drupal_set_message($message); + } + else { + // A fatal error occurred during batch processing. + $error_operation = reset($operations); + $operation = array_shift($error_operation); + $arguments = array_shift($error_operation); $arguments_as_string = implode(', ', $arguments); - - watchdog('openlayers_proximity', "Index rebuild: error when calling operation '%s'('%s')", array($operation, $arguments_as_string)); - drupal_set_message(t('An error occurred and has been recorded in the system log.'), 'error'); - } + + watchdog('openlayers_proximity', "Index rebuild: error when calling operation '%s'('%s')", array($operation, $arguments_as_string)); + drupal_set_message(t('An error occurred and has been recorded in the system log.'), 'error'); + } } /** @@ -225,7 +223,9 @@ function openlayers_proximity_build_node_index($node) { $index = module_invoke_all('build_proximity_index', $node); drupal_alter('build_proximity_index', $node, $index); - db_query('DELETE FROM {openlayers_proximity} WHERE nid = %d', $node->nid); + db_delete('openlayers_proximity') + ->condition('nid', $node->nid) + ->execute(); $location->nid = $node->nid; foreach ($index as $item) { $location->lat = $item[0]; @@ -236,15 +236,15 @@ function openlayers_proximity_build_node_index($node) { } /** - * Implementation of hook_build_proximity_index() + * Implements hook_build_proximity_index(). */ function openlayers_proximity_build_proximity_index($node) { $index = array(); foreach (openlayers_proximity_get_wkt_fields($node->type) as $name => $field) { - $item = $node->{$name}[0]; - if (!module_invoke($field['module'], 'content_is_empty', $item, $field)) { + $item = $node->{$name}['und'][0]; + if (!module_invoke($field['module'], 'field_is_empty', $item, $field)) { foreach (module_implements('parse_wkt') as $module) { - $index += module_invoke($module, 'parse_wkt', $item[OPENLAYERS_PROXIMITY_FIELD_TYPE]); + $index += module_invoke($module, 'parse_wkt', $item['wkt']); } drupal_alter('parse_wkt', $index, $field); } @@ -254,17 +254,22 @@ function openlayers_proximity_build_proximity_index($node) { /** * Get WKT field for the specified content type - * + * * @param $type Content type */ function openlayers_proximity_get_wkt_fields($type) { static $fields = array(); - + if (!isset($fields[$type])) { - $fields[$type] = content_fields(NULL, $type); - foreach ($fields[$type] as $key => $field) { - if ($field['type'] != OPENLAYERS_PROXIMITY_FIELD_TYPE) { - unset($fields[$type][$key]); + $everything = field_info_instances(); + foreach ($everything as $entity => $bundles) { + foreach ($bundles as $bundle => $bundlefields) { + foreach ($bundlefields as $key => $field) { + $real_field = field_info_field($field['field_name']); + if ($real_field['type'] == OPENLAYERS_PROXIMITY_FIELD_TYPE) { + $fields[$type][$key] = $real_field; + } + } } } } @@ -272,21 +277,26 @@ function openlayers_proximity_get_wkt_fields($type) { } /** - * Implementation of hook_openlayers_proximity_get_types() + * Implements hook_openlayers_proximity_get_types(). */ function openlayers_proximity_openlayers_proximity_get_types() { $types = array(); - $fields = content_fields(); - foreach ($fields as $field) { - if ($field['type'] == OPENLAYERS_PROXIMITY_FIELD_TYPE) { - $types[$field['type_name']] = $field['type_name']; + $fields = field_info_instances(); + foreach ($fields as $entity => $bundles) { + foreach ($bundles as $bundle => $bundlefields) { + foreach ($bundlefields as $field) { + $real_field = field_info_field($field['field_name']); + if ($real_field['type'] == OPENLAYERS_PROXIMITY_FIELD_TYPE) { + $types[$bundle] = $bundle; + } + } } } return $types; } /** - * Implementation of hook_parse_wkt() + * Implements hook_parse_wkt(). * Return array of lat/lon pairs. */ function openlayers_proximity_parse_wkt($wkt) { @@ -294,7 +304,9 @@ function openlayers_proximity_parse_wkt($wkt) { preg_match_all(OPENLAYERS_PROXIMITY_REGEX, $wkt, $matches); $points = array(); foreach ($matches[0] as $wkt) { - $points[] = array_reverse(explode(' ', $wkt)); + if (strlen($wkt) > 1) { + $points[] = array_reverse(explode(' ', $wkt)); + } } return $points; } @@ -318,8 +330,8 @@ function openlayers_proximity_get_available_units_for_select() { } /** - * Implementation of hook_measurement_units() - * + * Implements hook_measurement_units(). + * * Expose available units of measurement. To perform conversion * we must implement, for each unit, it respective: * hook_measurement_units_convert_() @@ -327,15 +339,15 @@ function openlayers_proximity_get_available_units_for_select() { function openlayers_proximity_measurement_units() { return array( 'km' => array( - 'long' => t('Kilometers'), + 'long' => t('Kilometers'), 'short' => t('Km'), 'const' => 1, - ), + ), 'miles' => array( - 'long' => t('Miles'), + 'long' => t('Miles'), 'short' => t('Mi'), 'const' => 1.609344, - ), + ), ); } @@ -363,7 +375,7 @@ function openlayers_proximity_measurement_units_convert_back($unit, $value) { /** * Query Google geocoding web service. - * + * * @param $address Address or location name. * @return Geocoder response. */ @@ -376,18 +388,18 @@ function openlayers_proximity_geocode($address) { $args['oe'] = 'utf-8'; $args['sensor'] = 'false'; $query = http_build_query($args, '', '&'); - + if (function_exists("curl_init")) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, OPENLAYERS_PROXIMITY_GOOGLE_GEOCODER_URL . $query); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $result = curl_exec($ch); - curl_close($ch); + curl_close($ch); } else { $result = file_get_contents(OPENLAYERS_PROXIMITY_GOOGLE_GEOCODER_URL . $query); } - + $response = json_decode($result); if ($response->status == OPENLAYERS_PROXIMITY_GOOGLE_STATUS_OK) { diff --git a/tests/openlayers_proximity.test b/tests/openlayers_proximity.test index 79aa937..5ebf6ed 100644 --- a/tests/openlayers_proximity.test +++ b/tests/openlayers_proximity.test @@ -1,4 +1,5 @@ - t('Business logic test'), - 'description' => t('Business logic test.') , + 'description' => t('Business logic test.'), 'group' => t('Openlayers Proximity'), ); } @@ -19,7 +20,7 @@ class OpenlayersProximityUnitTestCase extends DrupalWebTestCase { function tearDown() { return; } - + function testWktParsing() { $points = openlayers_proximity_parse_wkt($this->wkt); $this->assertEqual($points[2][0] == 14.039547968691, t('WKT parsing ok.')); @@ -28,10 +29,10 @@ class OpenlayersProximityUnitTestCase extends DrupalWebTestCase { function testRuleInvokeNodeInsert() { $node = node_load(3816); $user = user_load($node->uid); - + // rules_invoke_event('node_insert', $node, $user, $node, $user); - } - + } + } diff --git a/views/openlayers_proximity_handler_field.inc b/views/openlayers_proximity_handler_field.inc index e4b2197..21e0520 100644 --- a/views/openlayers_proximity_handler_field.inc +++ b/views/openlayers_proximity_handler_field.inc @@ -11,17 +11,17 @@ class openlayers_proximity_handler_field extends views_handler_field_numeric { $this->definition['float'] = TRUE; return $options; } - + /** * Basic options for all sort criteria */ function options_form(&$form, &$form_state) { - + if ($handlers = $this->view->display_handler->get_handlers('filter')) { $options = array(); foreach ($handlers as $name => $handler) { if ($handler->definition['handler'] == 'openlayers_proximity_handler_filter_circle') { - $options[$name] = $handler->definition['group'] .': '. $handler->definition['title'] .' ('. $handler->admin_summary() .')'; + $options[$name] = $handler->definition['group'] . ': ' . $handler->definition['title'] . ' (' . $handler->admin_summary() . ')'; } } $form['location_provider'] = array( @@ -32,7 +32,7 @@ class openlayers_proximity_handler_field extends views_handler_field_numeric { } parent::options_form($form, $form_state); } - + function query() { $handler = $this->view->display_handler->get_handler('filter', $this->options['location_provider']); if ($handler && $handler->value['location'] && isset($this->query->table_queue[$handler->table_formula_alias()])) { @@ -64,7 +64,7 @@ class openlayers_proximity_handler_field extends views_handler_field_numeric { } $units = openlayers_proximity_get_available_units(); - return check_plain($this->options['prefix'] . $value . ' '. $units[$unit]['short'] .' '. $this->options['suffix']); + return check_plain($this->options['prefix'] . $value . ' ' . $units[$unit]['short'] . ' ' . $this->options['suffix']); } } diff --git a/views/openlayers_proximity_handler_filter.inc b/views/openlayers_proximity_handler_filter.inc index c4d5cf8..db4086c 100644 --- a/views/openlayers_proximity_handler_filter.inc +++ b/views/openlayers_proximity_handler_filter.inc @@ -1,9 +1,10 @@ -op_process('between', $field); @@ -12,7 +13,7 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { function op_simple($field) { $this->op_process('simple', $field); } - + function op_process($op = 'simple', $field) { $this->secure_input(); @@ -23,7 +24,7 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { $this->process_location_proximity(); } } - + /** * Display the filter on the administrative summary */ @@ -40,7 +41,7 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { $output .= ' ' . t('@value @unit from @location', array('@value' => $this->value['value'], '@unit' => $this->value['unit'], '@location' => $this->value['location'])); } return $output; - } + } /** * Information about options for all kinds of purposes will be held here. @@ -80,36 +81,33 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { /** * Handle the 'left' side fo the exposed options form. */ - function expose_form_left(&$form, &$form_state) { + function expose_form(&$form, &$form_state) { + parent::expose_form($form, $form_state); $this->expose_option_form($form, 'unit', 'unit of measurement'); $this->expose_option_form($form, 'location', 'location'); $this->expose_option_form($form, 'node', 'node'); - parent::expose_form_left($form, $form_state); } /** * Validate the options form. */ function expose_validate($form, &$form_state) { - parent::expose_validate($form, &$form_state); + parent::expose_validate($form, $form_state); // @todo: validation. } - + /** * Provide a simple textfield for equality */ function value_form(&$form, &$form_state) { parent::value_form($form, $form_state); - - $form['value']['wrapper_open']['#value'] = '
'; - $form['value']['wrapper_location_open']['#value'] = '
'; + $form['value']['location'] = array( '#title' => t('Location'), '#type' => 'textfield', '#size' => 20, '#default_value' => $this->options['value']['location'], '#description' => t('Location where to start to search from.'), - '#process' => array('views_process_dependency'), '#dependency' => array( 'radio:options[location_as]' => array('location'), ), @@ -120,12 +118,10 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { '#default_value' => $this->options['value']['node'], '#options' => $this->get_node_options(), '#description' => t('Node where to start to search from.'), - '#process' => array('views_process_dependency'), '#dependency' => array( 'radio:options[location_as]' => array('node'), ), ); - $form['value']['wrapper_location_close']['#value'] = '
'; $form['value']['unit'] = array( '#title' => t('Unit of measurement'), '#type' => 'select', @@ -135,7 +131,6 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { '#prefix' => '
', '#suffix' => '
', ); - $form['value']['wrapper_close']['#value'] = '
'; $form['location_as'] = array( '#type' => 'radios', '#title' => t('Location'), @@ -146,53 +141,62 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { ), ); } - + /** * Provide a form for setting the operator. */ function operator_form(&$form, &$form_state) { parent::operator_form($form, $form_state); - // At the end of the day proximity search is a rough estimation. + // At the end of the day proximity search is a rough estimation. $this->unset_attributes($form['operator']['#options'], array('<=', '=', '!=', '>=')); } - + /** * Render our chunk of the exposed filter form when selecting */ function exposed_form(&$form, &$form_state) { - + if (empty($this->options['exposed'])) { return; } - + $force_operator = FALSE; $operators = $this->operator_options(); if (empty($this->options['expose']['use_operator'])) { $this->options['expose']['use_operator'] = TRUE; $force_operator = TRUE; } - + parent::exposed_form($form, $form_state); - + if ($force_operator) { $operator = $this->options['expose']['operator']; $form[$operator]['#type'] = 'hidden'; - $form[$operator]['#value'] = $form[$operator]['#default_value']; + $form[$operator]['#value'] = $form[$operator]['#default_value']; $this->unset_attributes($form[$operator], array('#options')); } - + // When exposed pull location and unit out of value form item. if (!empty($this->options['expose']['identifier'])) { - + // Unset useless form elements. $filter = &$form[$this->options['expose']['identifier']]; - $this->unset_attributes($filter, array('wrapper_open', 'wrapper_close', 'wrapper_location_open', 'wrapper_location_close')); + + // Strip dependencies off on exposed form. + $key = $this->options['expose']['identifier']; + foreach (element_children($form[$key]) as $el) { + if (!empty($form[$key][$el]['#dependency']) && $form[$key][$el]['#title'] == 'Location') { + $form[$key][$el]['#dependency'] = array(); + } + } + + $this->unset_attributes($form, array('location_as')); - + // Turn exposed form into a fieldset to have better control over its rendering. $filter['#type'] = 'fieldset'; - $filter['#attributes'] = array('class' => "openlayers-proximity-filter-exposed"); - + $filter['#attributes'] = array('class' => array("openlayers-proximity-filter-exposed")); + // Expose unit of measurement form, if necessary. if ($this->filter_item_is_exposed('unit')) { $name = $this->rename_exposed_filter_item($form, 'unit'); @@ -201,9 +205,9 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { else { $this->unset_attributes($filter, array('unit')); } - + // Expose location form, if necessary. - $name = $this->options['location_as']; + $name = $this->options['location_as']; if ($this->filter_item_is_exposed($name)) { $name = $this->rename_exposed_filter_item($form, $name); @@ -214,9 +218,9 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { } else { $this->unset_attributes($filter, array($name)); - $filter[$name]['#value'] = $this->filter_item_is_exposed('unit') ? '
'. $this->get_suffix() .'
' : ''; - } - + $filter[$name]['#value'] = $this->filter_item_is_exposed('unit') ? '
' . $this->get_suffix() . '
' : ''; + } + if ($this->options['location_as'] == 'location') { $this->unset_attributes($filter, array('node')); } @@ -226,24 +230,24 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { // Add meaningful suffix to value. if (isset($filter['value'])) { - + $filter['value']['#size'] = 3; $filter['value']['#field_prefix'] = $force_operator ? $operators[$this->options['operator']] : ''; - $filter['value']['#field_suffix'] = $this->get_suffix();; + $filter['value']['#field_suffix'] = $this->get_suffix(); $this->unset_attributes($filter['value'], array('#default_value')); } - + // Add meaningful prefix/suffix to min max. if (isset($filter['min']) && isset($filter['max'])) { - + $filter['min']['#size'] = 3; $filter['min']['#field_prefix'] = $force_operator ? $operators[$this->options['operator']] : ''; $filter['max']['#size'] = 3; $filter['max']['#field_prefix'] = t('and'); $filter['max']['#field_suffix'] = $this->get_suffix(); - + $this->unset_attributes($filter['max'], array('#title', '#default_value')); $this->unset_attributes($filter['min'], array('#default_value')); } @@ -254,45 +258,44 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { /** * Validate the exposed filter form */ - function exposed_validate(&$form, &$form_state) { - parent::exposed_validate(&$form, &$form_state); - + function exposed_validate(&$form, &$form_state) { + parent::exposed_validate($form, $form_state); // Satitize "value", "min" and "max" $operators = $this->operators(); $identifier = $this->options['expose']['identifier']; $location = $this->options['expose']['location']; foreach (array('value', 'min', 'max') as $field) { - $form_state['input'][$identifier][$field] = str_replace(',', '.', $form_state['input'][$identifier][$field]); + $form_state['values'][$identifier][$field] = str_replace(',', '.', $form_state['values'][$identifier][$field]); } - $values = $form_state['input']; + $values = $form_state['values']; $op = $values[$this->options['expose']['operator']]; - - // Validate "value", "min" and "max" - $fields = ($operators[$op]['method'] == 'op_between') ? array('min', 'max') : array('value'); + + // Validate "value", "min" and "max" + $fields = ($operators[$op]['method'] == 'op_between') ? array('min', 'max') : array('value'); foreach ($fields as $key => $field) { if ($values[$identifier][$field]) { if (!is_numeric($values[$identifier][$field])) { - form_set_error($identifier .']['. $field, t('Please, provide a valid numeric value.')); + form_set_error($identifier . '][' . $field, t('Please, provide a valid numeric value.')); } elseif ($values[$identifier][$field] <= 0) { - form_set_error($identifier .']['. $field, t('Please, provide a value greater then zero.')); + form_set_error($identifier . '][' . $field, t('Please, provide a value greater then zero.')); } elseif ($key && $values[$identifier]['min'] >= $values[$identifier]['max']) { - form_set_error($identifier .'][min', t('Please, make sure that the first value is greater then the second one.')); + form_set_error($identifier . '][min', t('Please, make sure that the first value is greater then the second one.')); } } } - - // Validate location + + // Validate location if ($this->options['location_as'] == 'location' && !empty($values[$identifier][$location])) { if ($response = openlayers_proximity_geocode($values[$identifier][$location])) { $this->response = $response; } else { - form_set_error($identifier .']['. $location, t('Location not found')); + form_set_error($identifier . '][' . $location, t('Location not found')); } } - + } /** @@ -302,14 +305,14 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { */ function process_node_proximity() { $nid = $this->value['node']; - + // Get square boundaries. - $x1 = db_result(db_query("SELECT lon FROM {openlayers_proximity} WHERE nid = %d ORDER BY lon ASC LIMIT 0, 1", $nid)); - $y1 = db_result(db_query("SELECT lat FROM {openlayers_proximity} WHERE nid = %d ORDER BY lat ASC LIMIT 0, 1", $nid)); - $x2 = db_result(db_query("SELECT lon FROM {openlayers_proximity} WHERE nid = %d ORDER BY lon DESC LIMIT 0, 1", $nid)); - $y2 = db_result(db_query("SELECT lat FROM {openlayers_proximity} WHERE nid = %d ORDER BY lat DESC LIMIT 0, 1", $nid)); - - $delta = (sqrt(pow($x1 - $x2, 2) + pow($y1 - $y2, 2)) / 2) * OPENLAYERS_PROXIMITY_KM_PER_LAT; + $x1 = db_query("SELECT lon FROM {openlayers_proximity} WHERE nid = :nid ORDER BY lon ASC LIMIT 0, 1", array(':nid' => $nid))->fetchField(); + $y1 = db_query("SELECT lat FROM {openlayers_proximity} WHERE nid = :nid ORDER BY lat ASC LIMIT 0, 1", array(':nid' => $nid))->fetchField(); + $x2 = db_query("SELECT lon FROM {openlayers_proximity} WHERE nid = :nid ORDER BY lon DESC LIMIT 0, 1", array(':nid' => $nid))->fetchField(); + $y2 = db_query("SELECT lat FROM {openlayers_proximity} WHERE nid = :nid ORDER BY lat DESC LIMIT 0, 1", array(':nid' => $nid))->fetchField(); + + $delta = (sqrt(pow($x1 - $x2, 2) + pow($y1 - $y2, 2)) / 2) * OPENLAYERS_PROXIMITY_KM_PER_LAT; $this->value['value'] += $delta; $this->value['min'] += $delta; $this->value['max'] += $delta; @@ -329,7 +332,7 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { } drupal_alter('process_location_proximity', $this->value); } - + function secure_input() { $this->value['value'] = isset($this->value['value']) ? $this->value['value'] : $this->options['value']['value']; $this->value['min'] = isset($this->value['min']) ? $this->value['min'] : $this->options['value']['min']; @@ -342,23 +345,22 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { $this->value['min'] = openlayers_proximity_measurement_units_convert($this->value['unit'], $this->value['min']); $this->value['max'] = openlayers_proximity_measurement_units_convert($this->value['unit'], $this->value['max']); } - + function unset_attributes(&$item, $attributes) { foreach ($attributes as $name) { unset($item[$name]); } - } - + } + function clean_exposed_filter_item(&$item) { $this->unset_attributes($item, array('#prefix', '#suffix', '#title', '#description')); } - + function expose_option_form(&$form, $name, $title) { - - $form['expose']['use_'. $name] = array( + $form['expose']['use_' . $name] = array( '#type' => 'checkbox', '#title' => t('Unlock @title', array('@title' => $title)), - '#default_value' => $this->options['expose']['use_'. $name], + '#default_value' => $this->options['expose']['use_' . $name], '#description' => t('When checked, this filter will be exposed to the user'), ); $form['expose'][$name] = array( @@ -367,11 +369,13 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { '#title' => t('@title identifier', array('@title' => $title)), '#size' => 40, '#description' => t('This will appear in the URL after the ? to identify this filter.'), - '#process' => array('views_process_dependency'), +/* + '#process' => array(' ctools_dependent_process'), +*/ '#dependency' => array( - 'edit-options-expose-use-'. $name => array(1) + 'edit-options-expose-use-' . $name => array(1), ), - ); + ); } @@ -384,29 +388,29 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { } return $value; } - + function filter_item_is_exposed($name) { - return !empty($this->options['expose']['use_'. $name]) && !empty($this->options['expose'][$name]); + return !empty($this->options['expose']['use_' . $name]) && !empty($this->options['expose'][$name]); } - + function get_node_options() { $options = array(); // Avoid query if filter is not exposed. @TODO: get a better condition check. if ($this->filter_item_is_exposed('node') && $this->options['location_as'] == 'node' || arg(2) == 'views') { - $results = db_query("SELECT n.title, n.nid FROM {openlayers_proximity} op LEFT JOIN {node} n ON n.nid = op.nid WHERE n.status = 1 ORDER BY n.title ASC"); - while ($row = db_fetch_object($results)) { + $results = db_query("SELECT n.title, n.nid FROM {openlayers_proximity} op LEFT JOIN {node} n ON n.nid = op.nid WHERE n.status = :nstatus ORDER BY n.title ASC", array(':nstatus' => 1))->fetchAllAssoc('nid'); + foreach ($results as $row) { $options[$row->nid] = check_plain(drupal_substr($row->title, 0, 40)); } } return $options; } - + function location_name() { if ($this->options['location_as'] == 'location') { return $this->options['value']['location']; } if ($this->options['location_as'] == 'node') { - return db_result(db_query("SELECT title FROM {node} WHERE nid = %d", $this->options['value']['node'])); + return db_query("SELECT title FROM {node} WHERE nid = :nid", array(':nid' => $this->options['value']['node']))->fetchField(); } } @@ -415,15 +419,15 @@ class openlayers_proximity_handler_filter extends views_handler_filter_float { $units = openlayers_proximity_get_available_units(); // If unit is not exposed add unit string to suffix. if (!$this->filter_item_is_exposed('unit')) { - $suffix = '@unit '. $suffix; + $suffix = '@unit ' . $suffix; } // If location is not exposed add location string to suffix. if (!$this->filter_item_is_exposed($this->options['location_as'])) { - $suffix = $suffix .' from @location'; + $suffix = $suffix . ' from @location'; } return t($suffix, array('@unit' => $units[$this->options['value']['unit']]['long'], '@location' => $this->location_name())); } -} \ No newline at end of file +} diff --git a/views/openlayers_proximity_handler_filter_circle.inc b/views/openlayers_proximity_handler_filter_circle.inc index 39a5756..aa9b993 100644 --- a/views/openlayers_proximity_handler_filter_circle.inc +++ b/views/openlayers_proximity_handler_filter_circle.inc @@ -1,50 +1,61 @@ -value['lat']) && !is_null($this->value['lon'])) { - + $join = new views_join(); $table = $this->table_formula_alias(); $join->definition['table formula'] = $this->table_formula($this->value['lat'], $this->value['lon']); $join->construct($table, 'node', 'nid', 'nid', array(), 'RIGHT'); - $this->query->queue_table($table, 'node', $join); + $this->query->add_table($table, 'node', $join); $this->query->add_field($table, 'distance'); - + if ($op == 'simple') { $radius = $this->value['value']; - $where = ($this->operator == '<') ? $this->build_where('<', $table, $radius) : $this->build_where('>', $table, $radius); + $operator = $this->operator; + $this->query->add_where($this->options['group'], $table.'.distance', $radius, $operator); } else { - $inner = $this->build_where('>', $table, $this->value['min']); - $outer = $this->build_where('<', $table, $this->value['max']); - $where = ($this->operator == 'between') ? "($inner AND $outer)" : "NOT($inner AND $outer)"; + if ($this->operator == 'between') { + $this->query->add_where($this->options['group'], $table.'.distance', array($this->value['min'], $this->value['max']), 'BETWEEN'); + } + else { + $this->query->add_where($this->options['group'], db_or()->condition($table.'.distance', $this->value['min'], '<')->condition($table.'.distance', $this->value['max'], '>')); + } } - $this->query->add_where($this->options['group'], $where); } $this->query->add_groupby("nid"); } /** - * Build WHERE clause. + * Build the subselect. */ - function build_where($operator, $alias, $radius) { - return sprintf("($alias.distance $operator= %f)", $radius); - } function table_formula($lat, $lon) { - $args = array('!lat1' => 'lat', '!lon1' => 'lon', '!lat2' => $lat, '!lon2' => $lon); - $great_circle = strtr(OPENLAYERS_PROXIMITY_SQL_GREAT_CIRCLE, $args); - return "(SELECT nid, lat, lon, $great_circle AS distance FROM {openlayers_proximity})"; + + $args = array( + ':lat2' => $lat, + ':lon2' => $lon, + ); + + $query = db_select('openlayers_proximity', 'op'); + $query->fields('op', array('nid')); + $query->fields('op', array('lat')); + $query->fields('op', array('lon')); + $query->addExpression(OPENLAYERS_PROXIMITY_SQL_GREAT_CIRCLE, 'distance', $args); + return $query; + } - + function table_formula_alias() { - return $this->table_alias .'_filter_'. $this->options['id']; + return $this->table_alias . '_filter_' . $this->options['id']; } } diff --git a/views/openlayers_proximity_handler_filter_square.inc b/views/openlayers_proximity_handler_filter_square.inc index 6294249..af6d6fd 100644 --- a/views/openlayers_proximity_handler_filter_square.inc +++ b/views/openlayers_proximity_handler_filter_square.inc @@ -1,7 +1,8 @@ -response) { - - $this->query->add_field($this->table_alias, 'lat'); - $this->query->add_field($this->table_alias, 'lon'); + + $table = $this->table_alias; + + $this->query->add_field($table, 'lat'); + $this->query->add_field($table, 'lon'); $lat = $this->value['lat']; $lon = $this->value['lon']; @@ -19,36 +22,38 @@ class openlayers_proximity_handler_filter_square extends openlayers_proximity_ha if ($op == 'simple') { $radius = $this->value['value']; $bounds = $this->get_bounds($lat, $lon, $radius); - $where = $this->build_where($this->operator, $bounds, $this->table_alias); + $operator = $this->operator; + $where = $this->build_where($this->operator, $bounds, $table); + //$this->query->add_where_expression($this->options['group'], $where); } else { $radius = $this->value['max']; $bounds = $this->get_bounds($lat, $lon, $radius); - $inner = $this->build_where('<', $bounds, $this->table_alias); - + $inner = $this->build_where('<', $bounds, $table); + $radius = $this->value['min']; $bounds = $this->get_bounds($lat, $lon, $radius); - $outer = $this->build_where('>', $bounds, $this->table_alias); + $outer = $this->build_where('>', $bounds, $table); $where = ($this->operator == 'between') ? "($inner AND $outer)" : "NOT($inner AND $outer)"; } - - $this->query->add_where($this->options['group'], $where); + + $this->query->add_where_expression($this->options['group'], $where); } $this->query->add_groupby("nid"); } - + /** * Calculate search bounds give lat/lon and distance in kilometers. * @see http://imaginerc.com/software/GeoCalc/ */ function get_bounds($latitude, $longitude, $radius) { - + // Calculate lat/lon shifts $latitude_shift = $radius / OPENLAYERS_PROXIMITY_KM_PER_LAT; $longitude_shift = (1 / (OPENLAYERS_PROXIMITY_KM_PER_LAT * cos($latitude * OPENLAYERS_PROXIMITY_DEGREE_TO_RADIANTS))) * $radius; - + // Calculate the boundaries $bounds = array(); $bounds['north'] = $latitude + $latitude_shift; @@ -57,14 +62,14 @@ class openlayers_proximity_handler_filter_square extends openlayers_proximity_ha $bounds['east'] = $longitude + $longitude_shift; return $bounds; } - - + + /** * Build WHERE clause. */ function build_where($operator, $bounds, $alias) { $where = vsprintf("($alias.lat <= %f AND $alias.lat >= %f AND $alias.lon >= %f AND $alias.lon <= %f)", $bounds); - return ($operator == '<' || $operator == '<=') ? $where : 'NOT'. $where; - } - -} \ No newline at end of file + return ($operator == '<' || $operator == '<=') ? $where : 'NOT' . $where; + } + +} diff --git a/views/openlayers_proximity_handler_sort.inc b/views/openlayers_proximity_handler_sort.inc index 9a7b2ab..df2c1a8 100644 --- a/views/openlayers_proximity_handler_sort.inc +++ b/views/openlayers_proximity_handler_sort.inc @@ -1,24 +1,25 @@ - ''); return $options; } - + /** * Basic options for all sort criteria */ function options_form(&$form, &$form_state) { - + if ($handlers = $this->view->display_handler->get_handlers('filter')) { $options = array(); foreach ($handlers as $name => $handler) { - if ($handler->definition['handler'] == 'openlayers_proximity_handler_filter_circle') { - $options[$name] = $handler->definition['group'] .': '. $handler->definition['title'] .' ('. $handler->admin_summary() .')'; - } + if ($handler->definition['handler'] == 'openlayers_proximity_handler_filter_circle') { + $options[$name] = $handler->definition['group'] . ': ' . $handler->definition['title'] . ' (' . $handler->admin_summary() . ')'; + } } $form['location_provider'] = array( '#title' => t('Location provider'), @@ -28,13 +29,13 @@ class openlayers_proximity_handler_sort extends views_handler_sort { } parent::options_form($form, $form_state); } - + function query() { $handler = $this->view->display_handler->get_handler('filter', $this->options['location_provider']); if ($handler && $handler->value['location'] && isset($this->query->table_queue[$handler->table_formula_alias()])) { $this->query->add_orderby($handler->table_formula_alias(), $this->real_field, $this->options['order']); } - + } - + }