I've put some major thought into this. neclimdul started off down the right path with this. He's got a database structure in here that looks like:

+---------+------------------+------+-----+---------+-------+
| Field   | Type             | Null | Key | Default | Extra |
+---------+------------------+------+-----+---------+-------+
| nid     | int(10) unsigned | NO   | PRI | NULL    |       |
| field   | varchar(32)      | NO   | PRI |         |       |
| content | varchar(255)     | NO   |     |         |       |
+---------+------------------+------+-----+---------+-------+

What I think I will have to do is just change nid to etid, and then add an entity_type column in addition to that to get the database structure right.

The hard part is with the views handler. This is due to the fact that we could be joining on any of entity_type tables. With Drupal 6 this is easy. The hard coded "node" table is exactly what I need, but not the case on Drupal 7. In addition, I don't see joining on every entity table a wise plan either as it will severely slow the query down. I need a way to figure out how to tell views that I only want the specified entity type and I haven't figured it out yet.

I was trying to take a hint from Organic Groups, but they do a hook_views_data_alter to make relationships for every entity table. I don't know quite how to translate this into my problem, but it looks promising.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

generalredneck’s picture

Assigned: Unassigned » generalredneck

I've been thinking... and maybe we can use the field API to our advantage in this case.

What if we have a "checkbox" that says "Natural Sort this Field". If it is checked then Another field is created that is the natural sort version of the field in question. Then I would have to have a views handler at all. It would mearly be using View's built in capabilities and having the user select to sort by that field. That "may" make the custom word list easier because then you might be able to do it per field, using hook_field_update and hook_field_insert to modify my new field. In addition, this field could be subject to anything you want to do to it including display and editing which brings up all kinds of other features.

This sounds like a pretty good size rework of how things are done now.

illmatix’s picture

+1

daggar’s picture

Seems like a good idea to me. I would like to use this to sort a non-title, ordinal field.

generalredneck’s picture

I'm actually working on this right now. Thanks for the support.

generalredneck’s picture

It looks like this update is only going to be limited to fields and nodes to start with. I'm finding it difficult to come up with an inclusive way to throw ALL entities and their text data structures into this while mapping them to existing views fields. This is already going to be a problem with modules that make copies of fields for purposes like throwing a different handler on. I think this would be an acceptable limitation though. Either make that module support me... or if it's asked for enough... I can add it in mine with an conditional looking for their module.

generalredneck’s picture

Not sure who all wants to take a look see, but you can follow my progress in the 7.x-2.x branch. What I've managed so far is to get a sort going for Node title and all text fields that have a limit to their size ("varchar" for the techies). By default, fields doesn't let you sort anything other than varchar, numeric, and date fields.

I've had to add a few fields to the database. One I haven't added yet but need to is a delta field for those fields that have carnality greater than 1.

Another interesting issue I've come across is that if you sort a field with carnality greater than 1 you will always get "duplicates" due to the way the query works. This really isn't a bug, though you will find it here in the views issue queue, so it's not specific to my module.

With that said, something I plan to do eventually is see if I can add an option to the "Multiple field settings" under the field handler that will allow you to naturally sort them when you display all values in the same row.

The next steps are to add a configuration section for the fields that you want to allow Natural Sorting on. It would be a shame and a big waste of database space to needlessly store all varchar fields in the views_natural_sort table. So the plan is to let you say which ones are allowed to be sorted and what you want to replace in each one (A, An, The type things). This will probably be on a "field instance" basis.

One last thing... I don't think I'm going to be able to supply an upgrade path for the views already out there... This means you will have to recreate your view when you upgrade to 2.x. That will be something I tackle later. I put myself at about a 1/3 of the way done.

generalredneck’s picture

Another update for those who are following...

I've decided that the fields part of the code should be a "seperate module". With that said, the module will be downloaded with views_natural_sort kinda like views and views_ui are packaged together. I did this because I don't know exactly how much of a performance hit storing field data into the database will be and then pulling it out later. But with that said, it will only be a click away in the modules configuration section.

Another reason I thought to do this is because it makes my code a heck of a lot cleaner. There are going to be special form alters that are going to be added just for the field configuration and what not so I didn't want to muk up the who module with that stuff... plus fields technically have their own special sort handler because the one I use for node titles wasn't up to the task.

Next, I've been debating on a dependency for the field portion, and instead of making everyone download that dependency, it would only make those who want to use the field portion download it.

This has been some enlightening stuff as well as a big PITA dealing with both views and field API, but I'm getting closer, I would say probably a little over halfway done. Also I've made some awesome abstraction improvements that makes the code a little more complicated, but easier to develop on as a whole.

Lastly, I'm adding some hooks and what not so that you can develop modules that will naturally sort more than just node titles and text fields of type varchar. In addition this this... you will also be able to control the "transformations" that cause the text to sort so specifically. For instance, in #546794 we added the ability to sort numeric data naturally. You may not want this, so you can choose to remove that transformation, and even add your own to the queue as well as conditionally cause a transformation to happen. This is for those developers out there that are using this module for some very special purpose and will be my framework for adding new transformations later.

Note: a transformation is something like removing specific words from the beginning of the string. See below:

<?php
function views_natural_sort_remove_beginning_words($string) {
    $beginning_words = variable_get('views_natural_sort_beginning_words_remove', array());
    if (empty($beginning_words)) {
      return $string;
    }
  
    array_walk($beginning_words, 'preg_quote');
    return preg_replace(
      '/^(' . implode('|', $beginning_words) . ')\s+/i',
      '',
      $string
    );
}
?>
generalredneck’s picture

Version: 7.x-1.x-dev » 7.x-2.0-alpha1
Status: Active » Needs review

Ladies & Gents,

I give you the release of Views Natural Sort 2.0 ALPHA. I'm not 100% sure about it's stability yet and would love it if a few of you would test it and see how it goes.

There is only an upgrade path for the views_natural_sort index table at the moment. All views must be recreated that used the old field handler as I changed the way that all worked.

Speaking of that, if you want to learn how to use the new module (I'll be adding some usability things soon), check out the quickly put together documentation.

Please feel free to bombard me with issues you find.

Speaking of that, you will need the devel module on for bits of this as I forgot and left some dvms in there. My bad!

antoniotorres’s picture

Thanks for the fantastic module. I tried using it with eck made entities to sort the titles and since titles aren't proper fields, it's unable to sort by it at all. Just a note for anyone else wondering.

wyrdwright’s picture

While trying to get this module working, I found that a text field in taxonomy term would only get one instance indexed. I think I found the source of the problem, and here's a small patch, which builds the data to be inserted into the table into the right structure for the admin batch.

vegardjo’s picture

Not getting this to work, using alpha5.

On a node view I only get the options on the node title, not on other text fields. On an entity view (custom entity with custom text fields) I don't get the option on any fields.

generalredneck’s picture

@vegardjo
looks like you found a bug. Regular "Text" fields (Not Long Text) should already be Naturally sortable. I just went through on simplytest.me and found this out for myself. Give me a couple of days to debug unless someone wants to donate time.

I moved this issue over to #2168661: Views Natural Sort is not sorting Text Fields

Andre-B’s picture

enabling indexing on a filled database might lead into problems, got one with 60k nodes here and I had to hack the set_time_limit(0); inside one of the batch files, currently I am waiting for the initialization step from Rebuilding Views Natural Sort Indexing Entries - this should be fixed somehow too. I am not sure why this takes so long, but creating the batch for processing the long running tasks is timing out without modifications in the first place ;)

now Ill leave, hoping for not running out of memory.

Update: ran out of memory, I guess this is due to:

function views_natural_sort_text_field_views_natural_sort_get_rebuild_data($entry_type) {
  if (!in_array($entry_type,views_natural_sort_text_field_views_natural_sort_get_entry_types())) {
    return array();
  }
  $field = field_info_field($entry_type['field']);
  $data = array();
  $entities = entity_load($entry_type['entity_type']);
  foreach ($entities as $entity) {
    $entries = _views_natural_sort_text_field_to_vns($entry_type['entity_type'], $entity, $field);
    if (!empty($entries)) {
      $data += $entries;
    }
  }
  return $data;
}

where as $entities = entity_load($entry_type['entity_type']); loads practically every single entity from the database inside of the script without any sort of batch processing.

Andre-B’s picture

after saving a node with this module enabled I get this error/ notice:

Warning: Invalid argument supplied for foreach() in _views_natural_sort_text_field_to_vns() (Zeile 113 von /project/sites/all/modules/views_natural_sort/views_natural_sort_text_field.module).

generalredneck’s picture

@Andre-b lets make this 2 separate issues. One for the time out and one for the warning.

@everyone as for progress on making this work for all entities I made some progress but nothing releasable. This is going to take me looking at entities schema info and matching them with views info. After that I will have to manage fields. Looking good though.

keep you up to date.

generalredneck’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.