@@ -104,19 +104,19 @@ public function __construct(auth $auth, config $config, driver_interface $db, la
104104 * Returns an array of ideas. Defaults to ten ideas ordered by date
105105 * excluding implemented, duplicate or invalid ideas.
106106 *
107- * @param int $number The number of ideas to return
108- * @param string $sort A sorting option/collection
109- * @param string $sort_direction Should either be ASC or DESC
110- * @param array|int $status The id of the status(es) to load
111- * @param int $start Start value for pagination
107+ * @param int $number The number of ideas to return
108+ * @param string $sort A sorting option/collection
109+ * @param string $direction Should either be ASC or DESC
110+ * @param array|int $status The id of the status(es) to load
111+ * @param int $start Start value for pagination
112112 *
113113 * @return array Array of row data
114114 */
115- public function get_ideas ($ number = 10 , $ sort = 'date ' , $ sort_direction = 'DESC ' , $ status = [], $ start = 0 )
115+ public function get_ideas ($ number = 10 , $ sort = 'date ' , $ direction = 'DESC ' , $ status = [], $ start = 0 )
116116 {
117117 // Initialize a query to request ideas
118118 $ this ->query_ideas ()
119- ->query_sort ($ sort , $ sort_direction )
119+ ->query_sort ($ sort , $ direction )
120120 ->query_status ($ status );
121121
122122 // For pagination, get a count of the total ideas being requested
@@ -155,9 +155,9 @@ protected function query_ideas()
155155 {
156156 $ this ->sql = [];
157157
158- $ this ->sql ['SELECT ' ][] = 't.topic_last_post_time, t.topic_status, t.topic_visibility, i.* ' ;
159- $ this ->sql ['FROM ' ] = "{$ this ->table_ideas } i " ;
160- $ this ->sql ['JOIN ' ] = "{$ this ->table_topics } t ON i.topic_id = t.topic_id " ;
158+ $ this ->sql ['SELECT ' ][] = 't.topic_last_post_time, t.topic_status, t.topic_visibility, i.* ' ;
159+ $ this ->sql ['FROM ' ] = "{$ this ->table_ideas } i " ;
160+ $ this ->sql ['JOIN ' ] = "{$ this ->table_topics } t ON i.topic_id = t.topic_id " ;
161161 $ this ->sql ['WHERE ' ][] = 't.forum_id = ' . (int ) $ this ->config ['ideas_forum_id ' ];
162162
163163 // Only get approved topics for regular users, Moderators will see unapproved topics
@@ -183,39 +183,38 @@ protected function query_sort($sort, $direction)
183183 $ sort = strtolower ($ sort );
184184 $ direction = $ direction === 'DESC ' ? 'DESC ' : 'ASC ' ;
185185
186- switch ($ sort )
186+ // Most sorting relies on simple ORDER BY statements, but some may use a WHERE statement
187+ $ sorting = [
188+ self ::SORT_DATE => ['ORDER_BY ' => 'i.idea_date ' ],
189+ self ::SORT_TITLE => ['ORDER_BY ' => 'i.idea_title ' ],
190+ self ::SORT_AUTHOR => ['ORDER_BY ' => 'i.idea_author ' ],
191+ self ::SORT_SCORE => ['ORDER_BY ' => 'CAST(i.idea_votes_up AS decimal) - CAST(i.idea_votes_down AS decimal) ' ],
192+ self ::SORT_VOTES => ['ORDER_BY ' => 'i.idea_votes_up + i.idea_votes_down ' ],
193+ self ::SORT_TOP => ['WHERE ' => 'i.idea_votes_up > i.idea_votes_down ' ],
194+ self ::SORT_MYIDEAS => ['ORDER_BY ' => 'i.idea_date ' , 'WHERE ' => 'i.idea_author = ' . (int ) $ this ->user ->data ['user_id ' ]],
195+ ];
196+
197+ // Append the new WHERE statement if the sort has one
198+ if (isset ($ sorting [$ sort ]['WHERE ' ]))
187199 {
188- case self ::SORT_DATE :
189- case self ::SORT_TITLE :
190- case self ::SORT_AUTHOR :
191- $ this ->sql ['ORDER_BY ' ] = "i.idea_ {$ sort } {$ direction }" ;
192- break ;
193-
194- case self ::SORT_SCORE :
195- $ this ->sql ['ORDER_BY ' ] = 'CAST(i.idea_votes_up AS decimal) - CAST(i.idea_votes_down AS decimal) ' . $ direction ;
196- break ;
197-
198- case self ::SORT_VOTES :
199- $ this ->sql ['ORDER_BY ' ] = 'i.idea_votes_up + i.idea_votes_down ' . $ direction ;
200- break ;
201-
202- case self ::SORT_MYIDEAS :
203- $ this ->sql ['WHERE ' ][] = 'i.idea_author = ' . (int ) $ this ->user ->data ['user_id ' ];
204- $ this ->sql ['ORDER_BY ' ] = "i.idea_date DESC " ;
205- break ;
206-
207- case self ::SORT_TOP :
208- $ this ->sql ['WHERE ' ][] = 'i.idea_votes_up > i.idea_votes_down ' ;
209- // no break
210-
211- default :
212- // From http://evanmiller.org/how-not-to-sort-by-average-rating.html
213- $ this ->sql ['SELECT ' ][] = '((i.idea_votes_up + 1.9208) / (i.idea_votes_up + i.idea_votes_down) -
214- 1.96 * SQRT((i.idea_votes_up * i.idea_votes_down) / (i.idea_votes_up + i.idea_votes_down) + 0.9604) /
215- (i.idea_votes_up + i.idea_votes_down)) / (1 + 3.8416 / (i.idea_votes_up + i.idea_votes_down))
216- AS ci_lower_bound ' ;
217-
218- $ this ->sql ['ORDER_BY ' ] = 'ci_lower_bound ' . $ direction ;
200+ $ this ->sql ['WHERE ' ][] = $ sorting [$ sort ]['WHERE ' ];
201+ }
202+
203+ // If we have an ORDER BY that is our sort mode. The absence of an ORDER BY
204+ // means we will by default sort ideas based on their calculated score.
205+ if (isset ($ sorting [$ sort ]['ORDER_BY ' ]))
206+ {
207+ $ this ->sql ['ORDER_BY ' ] = "{$ sorting [$ sort ]['ORDER_BY ' ]} $ direction " ;
208+ }
209+ else
210+ {
211+ // https://www.evanmiller.org/how-not-to-sort-by-average-rating.html
212+ $ this ->sql ['SELECT ' ][] = '((i.idea_votes_up + 1.9208) / (i.idea_votes_up + i.idea_votes_down) -
213+ 1.96 * SQRT((i.idea_votes_up * i.idea_votes_down) / (i.idea_votes_up + i.idea_votes_down) + 0.9604) /
214+ (i.idea_votes_up + i.idea_votes_down)) / (1 + 3.8416 / (i.idea_votes_up + i.idea_votes_down))
215+ AS ci_lower_bound ' ;
216+
217+ $ this ->sql ['ORDER_BY ' ] = 'ci_lower_bound ' . $ direction ;
219218 }
220219
221220 return $ this ;
0 commit comments