views_natural_sort.module 7.83 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
<?php
/**
 * @file
 * Provides a views filter that sorts titles by a more natural manner by
 * ignoring articles like "The" and "A."
 *
 * Normal sort:
 * A Chorus Line
 * All American
 * Fiddler on the Roof
 * Oklahoma!
 * The King And I
 *
 * Natural sort:
 * All American
 * A Chorus Line
 * Fiddler on the Roof
 * The King And I
 * Oklahoma!
 */

/**
 * Implementation of hook_menu().
 */
function views_natural_sort_menu() {
  $items = array();

28
  $items['admin/config/views_natural_sort'] = array(
29
    'title' => 'Views Natural Sort',
30 31 32 33 34 35
    'description' => 'Configuration and settings for natural sorting.',
    'page callback' => 'system_admin_menu_block_page',
    'access arguments' => array('administer site configuration'),
    'file' => 'system.admin.inc',
    'file path' => drupal_get_path('module', 'system'),
  );
36
  $items['admin/config/views_natural_sort/rebuild_index'] = array(
37 38
    'title' => 'Rebuild Search Index',
    'description' => 'Rebuild Views Natural Sort\'s search index',
39
    'page callback' => 'drupal_get_form',
40 41 42 43 44 45 46 47 48 49
    'page arguments' => array('views_natural_sort_rebuild_index_form'),
    'access callback' => 'user_access',
    'access arguments' => array('administer views'),
    'file' => 'views_natural_sort.admin.inc',
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/config/views_natural_sort/settings'] = array(
    'title' => 'Configure Word Removal Lists',
    'description' => 'Set what words should be ignored when performing a natural sort.',
    'page callback' => 'drupal_get_form',
50 51 52 53
    'page arguments' => array('views_natural_sort_settings_form'),
    'access callback' => 'user_access',
    'access arguments' => array('administer views'),
    'file' => 'views_natural_sort.admin.inc',
54
    'type' => MENU_NORMAL_ITEM,
55 56 57 58 59
  );

  return $items;
}

60 61 62 63 64
/**
 * Implementation of hook_views_api().
 */
function views_natural_sort_views_api() {
  return array(
65
    'api' => 3.0,
66 67 68
  );
}

69
/**
70
 * Implements hook_views_natural_sort_get_entry_types().
71
 */
72 73 74 75 76 77 78
function views_natural_sort_views_natural_sort_get_entry_types() {
  return array(array(
    'entity_type' => 'node',
    'field' => 'title',
  ));
}

79 80 81
/**
 * Implements hook_views_natural_sort_get_rebuild_data();
 */
82 83 84 85
function views_natural_sort_views_natural_sort_get_rebuild_data($entry_type){
  if($entry_type['entity_type'] != 'node' || $entry_type['field'] != 'title') {
    return array();
  }
86
  module_load_include('inc', 'views_natural_sort', 'views_natural_sort.node');
87 88 89 90 91
  $result = db_select('node', 'n')
    ->fields('n', array('nid', 'title'))
    ->execute();
  $data = array();
  foreach ($result as $row ) {
92
    $data[] = _views_natural_sort_node_to_vns($row);
93 94 95 96 97 98 99 100 101 102
  }
  return $data;
}

/**
 * Implements hook_node_insert().
 *
 * This keeps our natural sort index up to date.
 */
function views_natural_sort_node_insert($node) {
103
  module_load_include('inc', 'views_natural_sort', 'views_natural_sort.node');
104 105 106 107 108 109 110 111 112
  _views_natural_sort_store_node($node);
}

/**
 * Implementation of hook_node_update().
 *
 * This keeps our natural sort index up to date.
 */
function views_natural_sort_node_update($node) {
113
  module_load_include('inc', 'views_natural_sort', 'views_natural_sort.node');
114 115 116 117 118 119 120 121 122
  _views_natural_sort_store_node($node);
}

/**
 * Implementation of hook_node_delete().
 *
 * This keep sour natural sort index clean.
 */
function views_natural_sort_node_delete($node) {
123
  module_load_include('inc', 'views_natural_sort', 'views_natural_sort.node');
124 125 126 127
  _views_natural_sort_remove_node($node);
}

/**
128
 * Store Multiple views_natural_sort entries
129
 *
130 131
 * @param array $index_entries
 *   An array of entries to store in the views_natural_sort table.
132
 *
133
 * @see views_natural_sort_store
134
 */
135 136 137 138
function views_natural_sort_store_multiple(array $index_entries) {
  foreach($index_entries as $entry) {
    views_natural_sort_store($entry);
  }
139 140
}

141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
/**
 * Save an entry to the database that represents a views_natural_sort index
 *
 * @param array $index_entry
 *   Mirrors the views_natural_sort table
 *     $eid - Entity Id of the item referenced
 *     $entity_type - The Entity Type. Ex. node
 *     $field - reference to the property or field name
 *     $delta - the item number in that field or property
 *     $content - The transformed data that a field will
 *                be sorted by.
 */

function views_natural_sort_store(array $index_entry) {
  //This should take a formatted object and store it into the views_natural_sort table.
  $string = views_natural_sort_transform($index_entry);

  // The size limit on the content field for views_natual_sort is sometimes not
  // enough. Lets truncate all data down to that size. I personally feel the
  // inaccuracy is an acceptable loss, as the bigger the string gets, the less
  // permanent the sort.
  //
  // TODO: Have this pick up off of the schema so if someone does a
  // hook_schema_alter() on me.
  return db_merge('views_natural_sort')
    ->key(array(
      'eid' => $index_entry['eid'],
      'entity_type' => $index_entry['entity_type'],
      'field' => $index_entry['field'],
      'delta' => $index_entry['delta'],
    ))
    ->fields(array(
      'eid' => $index_entry['eid'],
      'entity_type' => $index_entry['entity_type'],
      'field' => $index_entry['field'],
      'delta' => $index_entry['delta'],
      'content' => substr($string, 0, 255),
    ))
    ->execute();
}

/**
 * Remove a views_natural_sort index entry based on keys
 *
 * @param array $index_entry
 *   Mirrors the views_natural_sort table
 *     $eid - Entity Id of the item referenced
 *     $entity_type - The Entity Type. Ex. node
 *     $field - reference to the property or field name
 *     $delta - the item number in that field or property
 */
function views_natural_sort_remove($index_entry) {
  //TODO: Make sure all the keys are in the index_entry.
  return db_delete('views_natural_sort')
    ->condition('eid', $index_entry['eid'])
    ->condition('entity_type', $index_entry['entity_type'])
    ->condition('field', $index_entry['field'])
    ->condition('delta', $index_entry['delta'])
    ->execute();
200 201 202
}

/**
203 204 205 206
 * Encodes a string into an ascii-sortable string such as:
 *  - Leading articles in common languages are ingored: The A An El La Le Il
 *  - Unimportant punctuation is ignored: # ' " ( )
 *  - Unimportant words are ignored: and of or
207
 *
208 209 210 211 212 213
 * @param array $index_entry
 *   Mirrors the views_natural_sort table
 *     $eid - Entity Id of the item referenced
 *     $entity_type - The Entity Type. Ex. node
 *     $field - reference to the property or field name
 *     $delta - the item number in that field or property
214
 *
215 216
 * @return string
 *   The transformed string
217
 */
218 219 220 221 222 223 224 225
function views_natural_sort_transform($index_entry) {
  // Get copy the original string.
  $string = $index_entry['content'];
  module_load_include('inc', 'views_natural_sort', 'views_natural_sort');
  foreach (views_natural_sort_get_transformations($index_entry) as $transformation_method) {
    $string = $transformation_method($string);
  }
  return $string;
226 227
}

228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
/**
 * Get the full list of transformations to run when saving a natural sort entry.
 * @param array $index_entry
 *   The original entry to be written to the views_natural_sort table.
 *     $eid - Entity Id of the item referenced
 *     $entity_type - The Entity Type. Ex. node
 *     $field - reference to the property or field name
 *     $delta - the item number in that field or property
 *     $content - The transformed data that a field will
 *                be sorted by.
 *
 * @return array
 *   The final list of transformations.
 */
function views_natural_sort_get_transformations($index_entry) {
  $transformations = array(
    'views_natural_sort_remove_beginning_words',
    'views_natural_sort_remove_words',
    'views_natural_sort_remove_symbols',
    'views_natural_sort_numbers',
  );
  //Allow other modules to modify the transformation that happens here if needed.
  drupal_alter('views_natural_sort_transformations', $transformations, $index_entry);
  return $transformations;
}