I would like to create a random sort option, selectable from this module's sort block... I saw http://drupal.org/node/602152, and noticed that the current schema that comes with this module does seem to have the random_* field declared... but I couldn't figure out how to implement it in the current 7.x release... do I need to use hook_apachesolr_query_alter?

Any help is much appreciated!

Comments

pwolanin’s picture

You probably would use both hook_apachesolr_query_prepare() and hook_apachesolr_query_alter() to add the sort as described.

Basically something like this should work (untested, though):

function MYMODULE__apachesolr_query_prepare($query) {
  $sort = array(
    'title' => t('Randomize'),
    'default' => 'asc',
  );
  $query->setAvailableSort('random', $sort);
}

function MYMODULE__apachesolr_query_alter($query) {
  $mysort = implode(' ', $query->getParam('sort'));
  if (strpos($mysort, 'random') !== FALSE) {
    $query->replaceParam('sort', 'random_' . REQUEST_TIME . ' desc');
  }
}

This relies on the fact that the prepared, but not altered, query object is cached as the current query.

pwolanin’s picture

Status: Active » Fixed
jordanmagnuson’s picture

Awesome! That works perfectly. Thank you!

jordanmagnuson’s picture

Updated my random sorting method to work with browsing through paged results (so that results aren't randomized again on every page). Basically a random seed is cached for each user, and randomized again each time we visit the first page of results. Thought I'd post it here in case it might help someone in the future.

If anyone has feedback on a better way to do this, please let me know.

$mysort = implode(' ', $query->getParam('sort'));
if (strpos($mysort, 'random') !== FALSE) {
  global $user;
  $random_seed = REQUEST_TIME;
  // If browsing through paged results, cache the random seed for each user, so that results aren't randomized again on every page
  if ($query->page > 0 && $cache = cache_get('custom_helper_apachesolr_random_sort_seed_user_' . $user->uid, 'cache')) {
    $random_seed = $cache->data;
  }
  else {
    cache_set('custom_helper_apachesolr_random_sort_seed_user_' . $user->uid, $random_seed, 'cache', 60*60);
  }
  $query->replaceParam('sort', 'random_' . $random_seed . ' desc');
}
pwolanin’s picture

You should use the session for this sort of thing, not the cache.

jordanmagnuson’s picture

Yes, that makes a lot more sense! Thank you. Here's my updated code:

$mysort = implode(' ', $query->getParam('sort'));
if (strpos($mysort, 'random') !== FALSE) {
  // If browsing through paged results, save the random seed to session, so that results aren't randomized again on every page
  if ($query->page > 0 && isset($_SESSION['custom_helper_apachesolr_random_sort_seed'])) {
    $random_seed = $_SESSION['custom_helper_apachesolr_random_sort_seed'];
  }
  else {
    $random_seed = REQUEST_TIME;
    $_SESSION['custom_helper_apachesolr_random_sort_seed'] = $random_seed;
  }
  $query->replaceParam('sort', 'random_' . $random_seed . ' desc');
}

Status: Fixed » Closed (fixed)

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