Note: I spend a lot of time in this question explaining, what I've been trying to do, but the end goal is to be able to sort by content type in an arbitrary order. I'm then grouping on content type, and getting headings in my results as desired. If you can show me how to do it without hook_views_query_alter() I'd be just as happy, though why my solution isn't working is giving me an ulcer. I'd prefer to avoid creating a whole bunch of attachments since I'm dealing with about 20 types here, but I think that is the next thing I'll have to try if nobody can help me.
A few other answers here, have gotten me to where I feel I'm close, but I'm getting not results, hopefully someone here can see what I'm doing wrong.
My actual setup is more complex than this. Basically I have a variable in settings that gives me some details about the different content types I'm dealing with, including a weight value for each. I'm building my order by clause using those weight values, but that doesn't seem to be the problem, so here is the query taken to it's simplest form:
Given a view that loads a set of nodes of at least two different types, one of which (for the purposes of this function has a machine name of 'brief' and a human readable name of Briefs):
/**
* Implements hook_views_query_alter().
*/
function MYMODULE_views_query_alter(&$view, &$query) {
if ($view->name == "view_name" && $view->current_display == "display_block_name") {
$caseclause = 'CASE node_type WHEN "brief" THEN 1 ELSE 2 END';
array_unshift($view->query->orderby, array(
'field' => $caseclause,
'direction' => 'ASC'));
}
}
I would expect this to give me the node listing with Briefs listed first, and other types listed afterward. Instead I get no results. If I remove the alteration to $view->query->orderby I get results. I've tried checking for "Briefs" instead of "brief". I got the column name, by adding it as a sort in the view and seeing what the view itself used, but just in case I've also tried node.type and type as the column name to put in the case statement. I tried doing all of this with the $query object too, just in case.
I tried adding the CASE clause as $query->addExpression, setting an alias of order_col for the expression, intending to then order by that column, but the whole page stopped showing up. It is possible I did something wrong on that attempt, if you can make that work, please let me know.
So here's what I need: How can I make a CASE statement work in hook_views_query_alter(), or failing that, how can I sort content type by an arbitrary order?
Here's a really brief section of the configuration variable that I have in settings.php that I'm trying to get the weight value from to do my sort.
$conf['pubtype_bundles'] = array(
'brief' => array(
'name' => 'Briefs',
'weight' => 5,
'description' => 'Issue Briefs, Policy Briefs, and Briefing Notes',
'help' => '',
'types' => array(
'issue' => 'Issue Brief',
'policy' => 'Policy Brief',
'briefing' => 'Briefing Note',
),
'typehelp' => '',
),
'book' => array(
'name' => 'Books',
'weight' => 10,
'description' => '',
'help' => '',
'types' => array(
'book' => 'Book',
),
'typehelp' => '',
),
);