/**
  * Gets the parameter descriptions
  *
  * @return array the descriptions, indexed by allowed key
  */
 public function getParamDescription()
 {
     $ret = array('pageid' => 'Page ID to submit feedback for', 'revid' => 'Revision ID to submit feedback for', 'anontoken' => 'Token for anonymous users', 'bucket' => 'Which feedback widget was shown to the user', 'link' => 'Which link the user clicked on to get to the widget');
     $fields = ApiArticleFeedbackv5Utils::getFields();
     foreach ($fields as $f) {
         $ret[$f['afi_name']] = 'Optional feedback field, only appears on certain "buckets".';
     }
     return $ret;
 }
 public function fetchFeedback($pageId, $filter = 'visible', $filterValue = null, $sort = 'age', $sortOrder = 'desc', $limit = 25, $continue = null, $continueId)
 {
     $dbr = wfGetDB(DB_SLAVE);
     $ids = array();
     $rows = array();
     $rv = array();
     $direction = strtolower($sortOrder) == 'asc' ? 'ASC' : 'DESC';
     $continueDirection = $direction == 'ASC' ? '>' : '<';
     $order;
     $continueSql;
     $sortField;
     $ratingField = 0;
     $commentField = 0;
     // This is in memcache so I don't feel that bad re-fetching it.
     // Needed to join in the comment and rating tables, for filtering
     // and sorting, respectively.
     foreach (ApiArticleFeedbackv5Utils::getFields() as $field) {
         if ($field['afi_bucket_id'] == 1 && $field['afi_name'] == 'comment') {
             $commentField = $field['afi_id'];
         }
         if ($field['afi_bucket_id'] == 1 && $field['afi_name'] == 'found') {
             $ratingField = $field['afi_id'];
         }
     }
     // Build ORDER BY clause.
     switch ($sort) {
         case 'helpful':
             $sortField = 'af_net_helpfulness';
             $order = "af_net_helpfulness {$direction}, af_id {$direction}";
             $continueSql = "(af_net_helpfulness {$continueDirection} " . intVal($continue) . " OR (af_net_helpfulness = " . intVal($continue) . " AND af_id {$continueDirection} " . intval($continueId) . ") )";
             break;
         case 'rating':
             # TODO: null ratings don't seem to show up at all. Need to sort that one out.
             $sortField = 'rating';
             $order = "rating {$direction}, af_id {$direction}";
             $continueSql = "(rating.aa_response_boolean {$continueDirection} " . intVal($continue) . " OR (rating.aa_response_boolean = " . intVal($continue) . " AND af_id {$continueDirection} " . intval($continueId) . ") )";
             break;
         case 'age':
             # Default field, fall through
         # Default field, fall through
         default:
             $sortField = 'af_id';
             $order = "af_id {$direction}";
             $continueSql = "af_id {$continueDirection} " . intVal($continue);
             break;
     }
     // Build WHERE clause.
     // Filter applied , if any:
     $where = $this->getFilterCriteria($filter, $filterValue);
     // PageID:
     $where['af_page_id'] = $pageId;
     // Continue SQL, if any:
     if ($continue !== null) {
         $where[] = $continueSql;
     }
     // Only show bucket 1 (per Fabrice on 1/25)
     $where['af_bucket_id'] = 1;
     // Fetch the feedback IDs we need.
     /* I'd really love to do this in one big query, but MySQL
        doesn't support LIMIT inside IN() subselects, and since
        we don't know the number of answers for each feedback
        record until we fetch them, this is the only way to make
        sure we get all answers for the exact IDs we want. */
     $id_query = $dbr->select(array('aft_article_feedback', 'rating' => 'aft_article_answer', 'comment' => 'aft_article_answer'), array('af_id', 'af_net_helpfulness', 'rating.aa_response_boolean AS rating'), $where, __METHOD__, array('LIMIT' => $limit + 1, 'ORDER BY' => $order), array('rating' => array('LEFT JOIN', 'rating.aa_feedback_id = af_id AND rating.aa_field_id = ' . intval($ratingField)), 'comment' => array('LEFT JOIN', 'comment.aa_feedback_id = af_id AND comment.aa_field_id = ' . intval($commentField))));
     foreach ($id_query as $id) {
         $ids[] = $id->af_id;
         // Get the continue values from the last counted item.
         if (count($ids) == $limit) {
             $this->continue = $id->{$sortField};
             $this->continueId = $id->af_id;
         }
     }
     if (!count($ids)) {
         return array();
     }
     // Returned an extra row, meaning there's more to show.
     // Also, pop that extra one off, so we don't render it.
     if (count($ids) > $limit) {
         $this->showMore = true;
         array_pop($ids);
     }
     $rows = $dbr->select(array('aft_article_feedback', 'rating' => 'aft_article_answer', 'answer' => 'aft_article_answer', 'aft_article_field', 'aft_article_field_option', 'user', 'page'), array('af_id', 'af_bucket_id', 'afi_name', 'afo_name', 'answer.aa_response_text', 'answer.aa_response_boolean', 'answer.aa_response_rating', 'answer.aa_response_option_id', 'afi_data_type', 'af_created', 'user_name', 'af_user_ip', 'af_is_hidden', 'af_abuse_count', 'af_helpful_count', 'af_unhelpful_count', 'af_is_deleted', 'af_needs_oversight', 'af_revision_id', 'af_net_helpfulness', 'af_revision_id', 'page_latest', 'page_title', 'page_namespace', 'rating.aa_response_boolean AS rating'), array('af_id' => $ids), __METHOD__, array('ORDER BY' => $order), array('rating' => array('LEFT JOIN', 'rating.aa_feedback_id = af_id AND rating.aa_field_id = ' . intval($ratingField)), 'answer' => array('LEFT JOIN', 'af_id = answer.aa_feedback_id'), 'aft_article_field' => array('LEFT JOIN', 'afi_id = answer.aa_field_id'), 'aft_article_field_option' => array('LEFT JOIN', 'answer.aa_response_option_id = afo_option_id'), 'user' => array('LEFT JOIN', 'user_id = af_user_id'), 'page' => array('JOIN', 'page_id = af_page_id')));
     foreach ($rows as $row) {
         if (!array_key_exists($row->af_id, $rv)) {
             $rv[$row->af_id] = array();
             $rv[$row->af_id][0] = $row;
             $rv[$row->af_id][0]->user_name = $row->user_name ? $row->user_name : $row->af_user_ip;
         }
         $rv[$row->af_id][$row->afi_name] = $row;
     }
     return $rv;
 }