In my questions.php page in my Forum that i am creating, I am checking the GET['sort'] variable to know what to sort by, e.g. by votes, or, views etc etc. I have a drop down offering to sort by different things. But how do I make the sort that the page is on by the default value of the drop down list. This is what I have so far, but it is terribly long and messy. I'm sure there is a more professional way of doing it. If you can enlighten me, please do!
if(isset($_GET['sort']) && $_GET['sort']=='answers'){
$questions = Question::find_most_answered();
$page_title = 'Showing most answered questions! - '.SITE_NAME;
$sortResults = "<select class=\"sortResults\" name=\"sortResult\" id=\"sortResult\">
<option value=\"questions.php?sort=answers\">Sorted By Most Answers</option>
<option value=\"questions.php?sort=votes\">Sorted By Most Voted</option>
<option value=\"questions.php?sort=recent\">Sorted By Most Recent</option>
<option value=\"questions.php?sort=oldest\">Sorted By Oldest</option>
<option value=\"questions.php?sort=views\">Sorted By Most Viewed</option>
</select>";
}else if(isset($_GET['sort']) && $_GET['sort']=='oldest'){
$questions = Question::find_oldest_questions();
$page_title = 'Showing oldest questions! - '.SITE_NAME;
$sortResults = "<select class=\"sortResults\" name=\"sortResult\" id=\"sortResult\">
<option value=\"questions.php?sort=oldest\">Sorted By Oldest</option>
<option value=\"questions.php?sort=answers\">Sorted By Most Answers</option>
<option value=\"questions.php?sort=votes\">Sorted By Most Voted</option>
<option value=\"questions.php?sort=recent\">Sorted By Most Recent</option>
<option value=\"questions.php?sort=views\">Sorted By Most Viewed</option>
</select>";
}else if(isset($_GET['sort']) && $_GET['sort']=='recent'){
$questions = Question::find_recent_questions();
$page_title = 'Showing most recent questions! - '.SITE_NAME;
$sortResults = "<select class=\"sortResults\" name=\"sortResult\" id=\"sortResult\">
<option value=\"questions.php?sort=recent\">Sorted By Most Recent</option>
<option value=\"questions.php?sort=answers\">Sorted By Most Answers</option>
<option value=\"questions.php?sort=votes\">Sorted By Most Voted</option>
<option value=\"questions.php?sort=oldest\">Sorted By Oldest</option>
<option value=\"questions.php?sort=views\">Sorted By Most Viewed</option>
</select>";
}else if(isset($_GET['sort']) && $_GET['sort']=='views'){
$questions = Question::find_most_viewed();
$page_title = 'Showing most viewed questions! - '.SITE_NAME;
$sortResults = "<select class=\"sortResults\" name=\"sortResult\" id=\"sortResult\">
<option value=\"questions.php?sort=views\">Sorted By Most Viewed</option>
<option value=\"questions.php?sort=votes\">Sorted By Most Voted</option>
<option value=\"questions.php?sort=answers\">Sorted By Most Answers</option>
<option value=\"questions.php?sort=recent\">Sorted By Most Recent</option>
<option value=\"questions.php?sort=oldest\">Sorted By Oldest</option>
</select>";
}else{
$questions = Question::find_most_voted();
$page_title = 'Showing most voted questions! - '.SITE_NAME;
$sortResults = "<select class=\"sortResults\" name=\"sortResult\" id=\"sortResult\">
<option value=\"questions.php?sort=votes\">Sorted By Most Voted</option>
<option value=\"questions.php?sort=answers\">Sorted By Most Answers</option>
<option value=\"questions.php?sort=recent\">Sorted By Most Recent</option>
<option value=\"questions.php?sort=oldest\">Sorted By Oldest</option>
<option value=\"questions.php?sort=views\">Sorted By Most Viewed</option>
</select>";
}
Please help me if you can, and edit this to make it look nicer. I am not as expert at that.
Thanks a lot!
// establish a list of possible drop-down list options
// left-hand is the value, right hand is the "english" equivalent
$options = array(
'views' => 'Most Viewed',
'votes' => 'Most Voted',
'answers' => 'Most Ansers',
'recent' => 'Most Recent',
'oldest' => 'Oldest'
);
// determine the sort value
$sort = (isset($_GET['sort']) && array_key_exists($_GET['sort'],$options)
? $_GET['sort'] // Input was valid, accept it
: 'views'); // setup default sort here
// populate the questions list based on the sort
switch ($sort)
{
case 'views': $questions = Question::find_most_viewed(); break;
case 'votes': $questions = Question::find_most_voted(); break;
case 'answers': $questions = Question::find_most_answered(); break;
case 'recent': $questions = Question::find_recent_questions(); break;
case 'oldest': default: $questions = Question::find_oldest_questions(); break;
}
// Setup the title based on the $options value
$page_title = 'Showing '.$options[$sort].' questions! - '.SITE_NAME;
// populate the sortResults based on the value of $sort, and iterate over
// it to reduce redundancy
$sortResults = "<select class=\"sortResults\" name=\"sortResult\" id=\"sortResult\">";
foreach ($options as $k => $v){
// it matches the current sort, mark it as selected
// (I assume this is what you were going for by moving it to the
// top of the list?)
$selected = '';
if ($sort == $k) $selected = ' selected="selected"';
// it's not the current filter, so append it to $sortResults
$sortResults .= "<option value=\"questions.php?sort={$k}\"{$selected}>Sorted By {$v}</option>";
}
$sortResults .= "</select>";
Is probably how I'd tackle it.
$_GET
based on keys in that array (and default if it's an invalid or exempt entry)$sort
value.I would add each option as a string in an array at the top, based on the $_GET - choose which parts of the array to display. This way you can make one change on the array at the top too and it will fix and update all of the parts displaying it. To clean up the if statement hell, you need to learn about switch cases.
You can do this like that, its untested but should work.
<?php
$options[] = "<option value=\"questions.php?sort=answers\">Sorted By Most Answers</option>";
$options[] = "<option value=\"questions.php?sort=votes\">Sorted By Most Voted</option>";
$options[] = "<option value=\"questions.php?sort=recent\">Sorted By Most Recent</option>";
$options[] = "<option value=\"questions.php?sort=oldest\">Sorted By Oldest</option>";
$options[] = "<option value=\"questions.php?sort=views\">Sorted By Most Viewed</option>";
$option_ontop = 0;
if(!empty($_GET['sort'])) {
switch($_GET['sort']) {
case 'answers':
$option_ontop = 0;
$questions = Question::find_most_answered();
$page_title = 'Showing most answered questions! - '.SITE_NAME;
break;
case 'votes':
$option_ontop = 1;
$questions = Question::find_most_voted();
$page_title = 'Showing most voted questions! - '.SITE_NAME;
break;
case 'recent':
$option_ontop = 2;
$questions = Question::find_recent_questions();
$page_title = 'Showing most recent questions! - '.SITE_NAME;
break;
case 'oldest':
$option_ontop = 3;
$questions = Question::find_oldest_questions();
$page_title = 'Showing oldest questions! - '.SITE_NAME;
break;
case 'views':
$option_ontop = 4;
$questions = Question::find_most_viewed();
$page_title = 'Showing most viewed questions! - '.SITE_NAME;
break;
}
}
if($option_ontop > 0) {
$new_option_sort = array($options[$option_ontop]);
unset($options[$option_ontop]);
$new_option_sort = array_merge($new_option_sort, $options);
}
$sortResults = "<select class=\"sortResults\" name=\"sortResult\" id=\"sortResult\">"
foreach($new_option_sort AS $option) {
$sortResults .= $option;
}
$sortResults .= "</select>";
?>
I'd use a universal function and feed in the sort criteria you need as variables, instead of defining an entirely new function:
$questions = Question::find($criteria);
switch($_GET['sort'])
{
case 'answers':
$text = 'most answered';
break;
case 'oldest':
$text = 'oldest';
break;
case 'recent':
$text = 'most recent';
break;
case 'views':
$text = 'most viewed';
break;
default:
$text = 'most voted';
break;
}
$page_title = "Showing $text questions! - ".SITE_NAME;
$sortResults = "<select class=\"sortResults\" name=\"sortResult\" id=\"sortResult\"><option value=\"questions.php?sort=views\">Sorted By Most Viewed</option><option value=\"questions.php?sort=votes\">Sorted By Most Voted</option><option value=\"questions.php?sort=answers\">Sorted By Most Answers</option><option value=\"questions.php?sort=recent\">Sorted By Most Recent</option><option value=\"questions.php?sort=oldest\">Sorted By Oldest</option></select>";
And in your class:
public function find($criteria)
{
switch($_GET['sort'])
{
case 'answers':
$order = 'answers DESC';
break;
case 'oldest':
$order = 'post_date ASC';
break;
case 'recent':
$order = 'post_date DESC';
break;
case 'views':
$order = 'views DESC';
break;
default:
$order = 'votes DESC';
break;
}
// Use your $order variable for MySQL call
}
I tried to come up with the cleanest way to do this that I know how. Let me know what you think.
<?php
// set $sort to $_GET var or nothing if it's not set
$sort = isset($_GET['sort']) ? $_GET['sort'] : '';
// Options Array
$options = array(
'answers' => array('Most Answers',0),
'oldest' => array('Oldest',0),
'recent' => array('Most Recent',0),
'views' => array('Most Viewed',0),
'votes' => array('Most Voted',0)
);
switch($sort) {
case 'answers':
$questions = Question::find_most_answered();
$options[$sort][1] = 1;
break;
case 'oldest':
$questions = Question::find_oldest_questions();
$options[$sort][1] = 1;
break;
case 'recent':
$questions = Question::find_recent_questions();
$options[$sort][1] = 1;
break;
case 'views':
$questions = Question::find_most_viewed();
$options[$sort][1] = 1;
break;
case 'votes':
$questions = Question::find_most_voted();
$options[$sort][1] = 1;
break;
default:
$questions = Question::find_recent_questions();
break;
}
?>
<select class="sortResults" name="sortResult" id="sortResult">
<?php foreach($options as $key => $val) { ?>
<option value="questions.php?sort=<?php echo $key; ?>" <?php if($val[1] == 1) { echo "selected=\"selected\""; } ?>>Sorted By <?php echo $val[0]; ?></option>
<?php } ?>
</select>
<!-- more code... -->
Thanks everyone for all your help, I have taken a bi from everyone and this is my final code. Instead of having 5 different functions for all my different sort types, I have implemented Jamie's idea answer as follows...
switch($sort){
case 'newest':
$order = "ORDER BY created DESC, votes DESC, total_answers DESC ,views DESC ";
break;
case 'oldest':
$order = "ORDER BY created ASC, votes DESC, total_answers DESC ,views DESC ";
break;
case 'answers':
$order = "ORDER BY total_answers DESC, votes DESC, views DESC ";
break;
case 'votes':
$order = "ORDER BY votes DESC, total_answers DESC, views DESC ";
break;
case 'views':
$order = "ORDER BY views DESC, votes DESC, total_answers DESC ";
break;
default:
$order = "ORDER BY votes DESC, total_answers DESC, views DESC "; // Perhaps display 404
break;
}
I then have taken Brad's idea and created an array as follows...
$sorts = array(
'votes'=>'most voted',
'answers'=>'most answered',
'views'=>'most viewed',
'newest'=>'newest',
'oldest'=>'oldest'
);
Then lastly I have implemented the following code...
$sort = isset($_GET['sort']) && !empty($_GET['sort']) ? $_GET['sort'] : 'votes';
$questions = Question::find_by($sort);
$page_title = "Showing {$sorts[$sort]} questions! - ".SITE_NAME;
$sortResults = "<select class=\"sortResults\" name=\"sortResult\" id=\"sortResult\">";
foreach($sorts as $value=>$display){
if($value == $sort){
$sortResults .= "<option value=\"questions.php?sort={$value}\" selected=\"selected\" \">Sorted by {$value}</option>";
}else{
$sortResults .= "<option value=\"questions.php?sort={$value}\">Sort by {$value}</option>";
}
}
$sortResults .= "</select>";
Thanks again to everyone who helped me!