[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/mod/forum/ -> search.php (source)

   1  <?php
   2  
   3  // This file is part of Moodle - http://moodle.org/
   4  //
   5  // Moodle is free software: you can redistribute it and/or modify
   6  // it under the terms of the GNU General Public License as published by
   7  // the Free Software Foundation, either version 3 of the License, or
   8  // (at your option) any later version.
   9  //
  10  // Moodle is distributed in the hope that it will be useful,
  11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13  // GNU General Public License for more details.
  14  //
  15  // You should have received a copy of the GNU General Public License
  16  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  17  
  18  /**
  19   * @package   mod_forum
  20   * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  21   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  22   */
  23  
  24  require_once('../../config.php');
  25  require_once ('lib.php');
  26  
  27  $id = required_param('id', PARAM_INT);                  // course id
  28  $search = trim(optional_param('search', '', PARAM_NOTAGS));  // search string
  29  $page = optional_param('page', 0, PARAM_INT);   // which page to show
  30  $perpage = optional_param('perpage', 10, PARAM_INT);   // how many per page
  31  $showform = optional_param('showform', 0, PARAM_INT);   // Just show the form
  32  
  33  $user    = trim(optional_param('user', '', PARAM_NOTAGS));    // Names to search for
  34  $userid  = trim(optional_param('userid', 0, PARAM_INT));      // UserID to search for
  35  $forumid = trim(optional_param('forumid', 0, PARAM_INT));      // ForumID to search for
  36  $subject = trim(optional_param('subject', '', PARAM_NOTAGS)); // Subject
  37  $phrase  = trim(optional_param('phrase', '', PARAM_NOTAGS));  // Phrase
  38  $words   = trim(optional_param('words', '', PARAM_NOTAGS));   // Words
  39  $fullwords = trim(optional_param('fullwords', '', PARAM_NOTAGS)); // Whole words
  40  $notwords = trim(optional_param('notwords', '', PARAM_NOTAGS));   // Words we don't want
  41  
  42  $timefromrestrict = optional_param('timefromrestrict', 0, PARAM_INT); // Use starting date
  43  $fromday = optional_param('fromday', 0, PARAM_INT);      // Starting date
  44  $frommonth = optional_param('frommonth', 0, PARAM_INT);      // Starting date
  45  $fromyear = optional_param('fromyear', 0, PARAM_INT);      // Starting date
  46  $fromhour = optional_param('fromhour', 0, PARAM_INT);      // Starting date
  47  $fromminute = optional_param('fromminute', 0, PARAM_INT);      // Starting date
  48  if ($timefromrestrict) {
  49      $datefrom = make_timestamp($fromyear, $frommonth, $fromday, $fromhour, $fromminute);
  50  } else {
  51      $datefrom = optional_param('datefrom', 0, PARAM_INT);      // Starting date
  52  }
  53  
  54  $timetorestrict = optional_param('timetorestrict', 0, PARAM_INT); // Use ending date
  55  $today = optional_param('today', 0, PARAM_INT);      // Ending date
  56  $tomonth = optional_param('tomonth', 0, PARAM_INT);      // Ending date
  57  $toyear = optional_param('toyear', 0, PARAM_INT);      // Ending date
  58  $tohour = optional_param('tohour', 0, PARAM_INT);      // Ending date
  59  $tominute = optional_param('tominute', 0, PARAM_INT);      // Ending date
  60  if ($timetorestrict) {
  61      $dateto = make_timestamp($toyear, $tomonth, $today, $tohour, $tominute);
  62  } else {
  63      $dateto = optional_param('dateto', 0, PARAM_INT);      // Ending date
  64  }
  65  
  66  $PAGE->set_pagelayout('standard');
  67  $PAGE->set_url($FULLME); //TODO: this is very sloppy --skodak
  68  
  69  if (empty($search)) {   // Check the other parameters instead
  70      if (!empty($words)) {
  71          $search .= ' '.$words;
  72      }
  73      if (!empty($userid)) {
  74          $search .= ' userid:'.$userid;
  75      }
  76      if (!empty($forumid)) {
  77          $search .= ' forumid:'.$forumid;
  78      }
  79      if (!empty($user)) {
  80          $search .= ' '.forum_clean_search_terms($user, 'user:');
  81      }
  82      if (!empty($subject)) {
  83          $search .= ' '.forum_clean_search_terms($subject, 'subject:');
  84      }
  85      if (!empty($fullwords)) {
  86          $search .= ' '.forum_clean_search_terms($fullwords, '+');
  87      }
  88      if (!empty($notwords)) {
  89          $search .= ' '.forum_clean_search_terms($notwords, '-');
  90      }
  91      if (!empty($phrase)) {
  92          $search .= ' "'.$phrase.'"';
  93      }
  94      if (!empty($datefrom)) {
  95          $search .= ' datefrom:'.$datefrom;
  96      }
  97      if (!empty($dateto)) {
  98          $search .= ' dateto:'.$dateto;
  99      }
 100      $individualparams = true;
 101  } else {
 102      $individualparams = false;
 103  }
 104  
 105  if ($search) {
 106      $search = forum_clean_search_terms($search);
 107  }
 108  
 109  if (!$course = $DB->get_record('course', array('id'=>$id))) {
 110      print_error('invalidcourseid');
 111  }
 112  
 113  require_course_login($course);
 114  
 115  $params = array(
 116      'context' => $PAGE->context,
 117      'other' => array('searchterm' => $search)
 118  );
 119  
 120  $event = \mod_forum\event\course_searched::create($params);
 121  $event->trigger();
 122  
 123  $strforums = get_string("modulenameplural", "forum");
 124  $strsearch = get_string("search", "forum");
 125  $strsearchresults = get_string("searchresults", "forum");
 126  $strpage = get_string("page");
 127  
 128  if (!$search || $showform) {
 129  
 130      $PAGE->navbar->add($strforums, new moodle_url('/mod/forum/index.php', array('id'=>$course->id)));
 131      $PAGE->navbar->add(get_string('advancedsearch', 'forum'));
 132  
 133      $PAGE->set_title($strsearch);
 134      $PAGE->set_heading($course->fullname);
 135      echo $OUTPUT->header();
 136  
 137      forum_print_big_search_form($course);
 138      echo $OUTPUT->footer();
 139      exit;
 140  }
 141  
 142  /// We need to do a search now and print results
 143  
 144  $searchterms = str_replace('forumid:', 'instance:', $search);
 145  $searchterms = explode(' ', $searchterms);
 146  
 147  $searchform = forum_search_form($course, $search);
 148  
 149  $PAGE->navbar->add($strsearch, new moodle_url('/mod/forum/search.php', array('id'=>$course->id)));
 150  $PAGE->navbar->add($strsearchresults);
 151  if (!$posts = forum_search_posts($searchterms, $course->id, $page*$perpage, $perpage, $totalcount)) {
 152      $PAGE->set_title($strsearchresults);
 153      $PAGE->set_heading($course->fullname);
 154      echo $OUTPUT->header();
 155      echo $OUTPUT->heading($strforums, 2);
 156      echo $OUTPUT->heading($strsearchresults, 3);
 157      echo $OUTPUT->heading(get_string("noposts", "forum"), 4);
 158  
 159      if (!$individualparams) {
 160          $words = $search;
 161      }
 162  
 163      forum_print_big_search_form($course);
 164  
 165      echo $OUTPUT->footer();
 166      exit;
 167  }
 168  
 169  //including this here to prevent it being included if there are no search results
 170  require_once($CFG->dirroot.'/rating/lib.php');
 171  
 172  //set up the ratings information that will be the same for all posts
 173  $ratingoptions = new stdClass();
 174  $ratingoptions->component = 'mod_forum';
 175  $ratingoptions->ratingarea = 'post';
 176  $ratingoptions->userid = $USER->id;
 177  $ratingoptions->returnurl = $PAGE->url->out(false);
 178  $rm = new rating_manager();
 179  
 180  $PAGE->set_title($strsearchresults);
 181  $PAGE->set_heading($course->fullname);
 182  $PAGE->set_button($searchform);
 183  echo $OUTPUT->header();
 184  echo '<div class="reportlink">';
 185  echo '<a href="search.php?id='.$course->id.
 186                           '&amp;user='.urlencode($user).
 187                           '&amp;userid='.$userid.
 188                           '&amp;forumid='.$forumid.
 189                           '&amp;subject='.urlencode($subject).
 190                           '&amp;phrase='.urlencode($phrase).
 191                           '&amp;words='.urlencode($words).
 192                           '&amp;fullwords='.urlencode($fullwords).
 193                           '&amp;notwords='.urlencode($notwords).
 194                           '&amp;dateto='.$dateto.
 195                           '&amp;datefrom='.$datefrom.
 196                           '&amp;showform=1'.
 197                           '">'.get_string('advancedsearch','forum').'...</a>';
 198  echo '</div>';
 199  
 200  echo $OUTPUT->heading($strforums, 2);
 201  echo $OUTPUT->heading("$strsearchresults: $totalcount", 3);
 202  
 203  $url = new moodle_url('search.php', array('search' => $search, 'id' => $course->id, 'perpage' => $perpage));
 204  echo $OUTPUT->paging_bar($totalcount, $page, $perpage, $url);
 205  
 206  //added to implement highlighting of search terms found only in HTML markup
 207  //fiedorow - 9/2/2005
 208  $strippedsearch = str_replace('user:','',$search);
 209  $strippedsearch = str_replace('subject:','',$strippedsearch);
 210  $strippedsearch = str_replace('&quot;','',$strippedsearch);
 211  $searchterms = explode(' ', $strippedsearch);    // Search for words independently
 212  foreach ($searchterms as $key => $searchterm) {
 213      if (preg_match('/^\-/',$searchterm)) {
 214          unset($searchterms[$key]);
 215      } else {
 216          $searchterms[$key] = preg_replace('/^\+/','',$searchterm);
 217      }
 218  }
 219  $strippedsearch = implode(' ', $searchterms);    // Rebuild the string
 220  
 221  foreach ($posts as $post) {
 222  
 223      // Replace the simple subject with the three items forum name -> thread name -> subject
 224      // (if all three are appropriate) each as a link.
 225      if (! $discussion = $DB->get_record('forum_discussions', array('id' => $post->discussion))) {
 226          print_error('invaliddiscussionid', 'forum');
 227      }
 228      if (! $forum = $DB->get_record('forum', array('id' => "$discussion->forum"))) {
 229          print_error('invalidforumid', 'forum');
 230      }
 231  
 232      if (!$cm = get_coursemodule_from_instance('forum', $forum->id)) {
 233          print_error('invalidcoursemodule');
 234      }
 235  
 236      $post->subject = highlight($strippedsearch, $post->subject);
 237      $discussion->name = highlight($strippedsearch, $discussion->name);
 238  
 239      $fullsubject = "<a href=\"view.php?f=$forum->id\">".format_string($forum->name,true)."</a>";
 240      if ($forum->type != 'single') {
 241          $fullsubject .= " -> <a href=\"discuss.php?d=$discussion->id\">".format_string($discussion->name,true)."</a>";
 242          if ($post->parent != 0) {
 243              $fullsubject .= " -> <a href=\"discuss.php?d=$post->discussion&amp;parent=$post->id\">".format_string($post->subject,true)."</a>";
 244          }
 245      }
 246  
 247      $post->subject = $fullsubject;
 248      $post->subjectnoformat = true;
 249  
 250      //add the ratings information to the post
 251      //Unfortunately seem to have do this individually as posts may be from different forums
 252      if ($forum->assessed != RATING_AGGREGATE_NONE) {
 253          $modcontext = context_module::instance($cm->id);
 254          $ratingoptions->context = $modcontext;
 255          $ratingoptions->items = array($post);
 256          $ratingoptions->aggregate = $forum->assessed;//the aggregation method
 257          $ratingoptions->scaleid = $forum->scale;
 258          $ratingoptions->assesstimestart = $forum->assesstimestart;
 259          $ratingoptions->assesstimefinish = $forum->assesstimefinish;
 260          $postswithratings = $rm->get_ratings($ratingoptions);
 261  
 262          if ($postswithratings && count($postswithratings)==1) {
 263              $post = $postswithratings[0];
 264          }
 265      }
 266  
 267      // Identify search terms only found in HTML markup, and add a warning about them to
 268      // the start of the message text. However, do not do the highlighting here. forum_print_post
 269      // will do it for us later.
 270      $missing_terms = "";
 271  
 272      $options = new stdClass();
 273      $options->trusted = $post->messagetrust;
 274      $post->message = highlight($strippedsearch,
 275                      format_text($post->message, $post->messageformat, $options, $course->id),
 276                      0, '<fgw9sdpq4>', '</fgw9sdpq4>');
 277  
 278      foreach ($searchterms as $searchterm) {
 279          if (preg_match("/$searchterm/i",$post->message) && !preg_match('/<fgw9sdpq4>'.$searchterm.'<\/fgw9sdpq4>/i',$post->message)) {
 280              $missing_terms .= " $searchterm";
 281          }
 282      }
 283  
 284      $post->message = str_replace('<fgw9sdpq4>', '<span class="highlight">', $post->message);
 285      $post->message = str_replace('</fgw9sdpq4>', '</span>', $post->message);
 286  
 287      if ($missing_terms) {
 288          $strmissingsearchterms = get_string('missingsearchterms','forum');
 289          $post->message = '<p class="highlight2">'.$strmissingsearchterms.' '.$missing_terms.'</p>'.$post->message;
 290      }
 291  
 292      // Prepare a link to the post in context, to be displayed after the forum post.
 293      $fulllink = "<a href=\"discuss.php?d=$post->discussion#p$post->id\">".get_string("postincontext", "forum")."</a>";
 294  
 295      // Now pring the post.
 296      forum_print_post($post, $discussion, $forum, $cm, $course, false, false, false,
 297              $fulllink, '', -99, false);
 298  }
 299  
 300  echo $OUTPUT->paging_bar($totalcount, $page, $perpage, $url);
 301  
 302  echo $OUTPUT->footer();
 303  
 304  
 305   /**
 306    * Print a full-sized search form for the specified course.
 307    *
 308    * @param stdClass $course The Course that will be searched.
 309    * @return void The function prints the form.
 310    */
 311  function forum_print_big_search_form($course) {
 312      global $CFG, $DB, $words, $subject, $phrase, $user, $userid, $fullwords, $notwords, $datefrom, $dateto, $PAGE, $OUTPUT;
 313  
 314      echo $OUTPUT->box(get_string('searchforumintro', 'forum'), 'searchbox boxaligncenter', 'intro');
 315  
 316      echo $OUTPUT->box_start('generalbox boxaligncenter');
 317  
 318      echo html_writer::script('', $CFG->wwwroot.'/mod/forum/forum.js');
 319  
 320      echo '<form id="searchform" action="search.php" method="get">';
 321      echo '<table cellpadding="10" class="searchbox" id="form">';
 322  
 323      echo '<tr>';
 324      echo '<td class="c0"><label for="words">'.get_string('searchwords', 'forum').'</label>';
 325      echo '<input type="hidden" value="'.$course->id.'" name="id" alt="" /></td>';
 326      echo '<td class="c1"><input type="text" size="35" name="words" id="words"value="'.s($words, true).'" alt="" /></td>';
 327      echo '</tr>';
 328  
 329      echo '<tr>';
 330      echo '<td class="c0"><label for="phrase">'.get_string('searchphrase', 'forum').'</label></td>';
 331      echo '<td class="c1"><input type="text" size="35" name="phrase" id="phrase" value="'.s($phrase, true).'" alt="" /></td>';
 332      echo '</tr>';
 333  
 334      echo '<tr>';
 335      echo '<td class="c0"><label for="notwords">'.get_string('searchnotwords', 'forum').'</label></td>';
 336      echo '<td class="c1"><input type="text" size="35" name="notwords" id="notwords" value="'.s($notwords, true).'" alt="" /></td>';
 337      echo '</tr>';
 338  
 339      if ($DB->get_dbfamily() == 'mysql' || $DB->get_dbfamily() == 'postgres') {
 340          echo '<tr>';
 341          echo '<td class="c0"><label for="fullwords">'.get_string('searchfullwords', 'forum').'</label></td>';
 342          echo '<td class="c1"><input type="text" size="35" name="fullwords" id="fullwords" value="'.s($fullwords, true).'" alt="" /></td>';
 343          echo '</tr>';
 344      }
 345  
 346      echo '<tr>';
 347      echo '<td class="c0">'.get_string('searchdatefrom', 'forum').'</td>';
 348      echo '<td class="c1">';
 349      if (empty($datefrom)) {
 350          $datefromchecked = '';
 351          $datefrom = make_timestamp(2000, 1, 1, 0, 0, 0);
 352      }else{
 353          $datefromchecked = 'checked="checked"';
 354      }
 355  
 356      echo '<input name="timefromrestrict" type="checkbox" value="1" alt="'.get_string('searchdatefrom', 'forum').'" onclick="return lockoptions(\'searchform\', \'timefromrestrict\', timefromitems)" '.  $datefromchecked . ' /> ';
 357      $selectors = html_writer::select_time('days', 'fromday', $datefrom)
 358                 . html_writer::select_time('months', 'frommonth', $datefrom)
 359                 . html_writer::select_time('years', 'fromyear', $datefrom)
 360                 . html_writer::select_time('hours', 'fromhour', $datefrom)
 361                 . html_writer::select_time('minutes', 'fromminute', $datefrom);
 362      echo $selectors;
 363      echo '<input type="hidden" name="hfromday" value="0" />';
 364      echo '<input type="hidden" name="hfrommonth" value="0" />';
 365      echo '<input type="hidden" name="hfromyear" value="0" />';
 366      echo '<input type="hidden" name="hfromhour" value="0" />';
 367      echo '<input type="hidden" name="hfromminute" value="0" />';
 368  
 369      echo '</td>';
 370      echo '</tr>';
 371  
 372      echo '<tr>';
 373      echo '<td class="c0">'.get_string('searchdateto', 'forum').'</td>';
 374      echo '<td class="c1">';
 375      if (empty($dateto)) {
 376          $datetochecked = '';
 377          $dateto = time()+3600;
 378      }else{
 379          $datetochecked = 'checked="checked"';
 380      }
 381  
 382      echo '<input name="timetorestrict" type="checkbox" value="1" alt="'.get_string('searchdateto', 'forum').'" onclick="return lockoptions(\'searchform\', \'timetorestrict\', timetoitems)" ' .$datetochecked. ' /> ';
 383      $selectors = html_writer::select_time('days', 'today', $dateto)
 384                 . html_writer::select_time('months', 'tomonth', $dateto)
 385                 . html_writer::select_time('years', 'toyear', $dateto)
 386                 . html_writer::select_time('hours', 'tohour', $dateto)
 387                 . html_writer::select_time('minutes', 'tominute', $dateto);
 388      echo $selectors;
 389  
 390      echo '<input type="hidden" name="htoday" value="0" />';
 391      echo '<input type="hidden" name="htomonth" value="0" />';
 392      echo '<input type="hidden" name="htoyear" value="0" />';
 393      echo '<input type="hidden" name="htohour" value="0" />';
 394      echo '<input type="hidden" name="htominute" value="0" />';
 395  
 396      echo '</td>';
 397      echo '</tr>';
 398  
 399      echo '<tr>';
 400      echo '<td class="c0"><label for="menuforumid">'.get_string('searchwhichforums', 'forum').'</label></td>';
 401      echo '<td class="c1">';
 402      echo html_writer::select(forum_menu_list($course), 'forumid', '', array(''=>get_string('allforums', 'forum')));
 403      echo '</td>';
 404      echo '</tr>';
 405  
 406      echo '<tr>';
 407      echo '<td class="c0"><label for="subject">'.get_string('searchsubject', 'forum').'</label></td>';
 408      echo '<td class="c1"><input type="text" size="35" name="subject" id="subject" value="'.s($subject, true).'" alt="" /></td>';
 409      echo '</tr>';
 410  
 411      echo '<tr>';
 412      echo '<td class="c0"><label for="user">'.get_string('searchuser', 'forum').'</label></td>';
 413      echo '<td class="c1"><input type="text" size="35" name="user" id="user" value="'.s($user, true).'" alt="" /></td>';
 414      echo '</tr>';
 415  
 416      echo '<tr>';
 417      echo '<td class="submit" colspan="2" align="center">';
 418      echo '<input type="submit" value="'.get_string('searchforums', 'forum').'" alt="" /></td>';
 419      echo '</tr>';
 420  
 421      echo '</table>';
 422      echo '</form>';
 423  
 424      echo html_writer::script(js_writer::function_call('lockoptions_timetoitems'));
 425      echo html_writer::script(js_writer::function_call('lockoptions_timefromitems'));
 426  
 427      echo $OUTPUT->box_end();
 428  }
 429  
 430  /**
 431   * This function takes each word out of the search string, makes sure they are at least
 432   * two characters long and returns an string of the space-separated search
 433   * terms.
 434   *
 435   * @param string $words String containing space-separated strings to search for.
 436   * @param string $prefix String to prepend to the each token taken out of $words.
 437   * @return string The filtered search terms, separated by spaces.
 438   * @todo Take the hardcoded limit out of this function and put it into a user-specified parameter.
 439   */
 440  function forum_clean_search_terms($words, $prefix='') {
 441      $searchterms = explode(' ', $words);
 442      foreach ($searchterms as $key => $searchterm) {
 443          if (strlen($searchterm) < 2) {
 444              unset($searchterms[$key]);
 445          } else if ($prefix) {
 446              $searchterms[$key] = $prefix.$searchterm;
 447          }
 448      }
 449      return trim(implode(' ', $searchterms));
 450  }
 451  
 452   /**
 453    * Retrieve a list of the forums that this user can view.
 454    *
 455    * @param stdClass $course The Course to use.
 456    * @return array A set of formatted forum names stored against the forum id.
 457    */
 458  function forum_menu_list($course)  {
 459      $menu = array();
 460  
 461      $modinfo = get_fast_modinfo($course);
 462      if (empty($modinfo->instances['forum'])) {
 463          return $menu;
 464      }
 465  
 466      foreach ($modinfo->instances['forum'] as $cm) {
 467          if (!$cm->uservisible) {
 468              continue;
 469          }
 470          $context = context_module::instance($cm->id);
 471          if (!has_capability('mod/forum:viewdiscussion', $context)) {
 472              continue;
 473          }
 474          $menu[$cm->instance] = format_string($cm->name);
 475      }
 476  
 477      return $menu;
 478  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1