Example #1
0
 /**
  * Short description for 'collect'
  *
  * Long description (if any) ...
  *
  * @param      boolean $force_generic Parameter description (if any) ...
  * @return     unknown Return description (if any) ...
  */
 public function collect($force_generic = false)
 {
     if (!$this->terms->any() || !($positive_terms = $this->terms->get_positive_chunks())) {
         return;
     }
     $authz = new Authorization();
     $req = new Request($this->terms);
     $this->tags = $req->get_tags();
     $weighters = array('all' => array());
     $plugins = Plugin::byType('search');
     $this->custom_mode = true;
     // Poll custom result plugins, like the one that shows matching members at the top of the list
     if (!$force_generic) {
         foreach ($plugins as $plugin) {
             if (Plugin::isEnabled('search', $plugin->name)) {
                 $refl = new ReflectionClass("plgSearch{$plugin->name}");
                 if ($refl->hasMethod('onSearchCustom')) {
                     $this->current_plugin = $plugin->name;
                     if ($this->custom_title = $refl->getMethod('onSearchCustom')->invokeArgs(NULL, array($req, &$this, $authz))) {
                         break;
                     }
                 }
             }
         }
     }
     $this->custom_mode = false;
     foreach ($plugins as $plugin) {
         if (!Plugin::isEnabled('search', $plugin->name)) {
             continue;
         }
         $refl = new ReflectionClass("plgSearch{$plugin->name}");
         $this->current_plugin = $plugin->name;
         $weighters[$plugin->name] = array();
         // generic resource plugin
         if ($refl->hasMethod('onSearch')) {
             $refl->getMethod('onSearch')->invokeArgs(NULL, array($req, &$this, $authz));
         }
         $this->result_counts[$plugin->name] = array('friendly_name' => $refl->hasMethod('getName') ? $refl->getMethod('getName')->invoke(NULL) : ucwords($plugin->name), 'plugin_name' => $plugin->name, 'count' => 0);
         // custom results like Google does when you enter a stock symbol. tags used to be implemented this way, but they got moved into the core so other plugins could use them to find tagged results
         if ($refl->hasMethod('onSearchWidget')) {
             $refl->getMethod('onSearchWidget')->invokeArgs(NULL, array($req, &$this->widgets, $authz));
         }
         if ($refl->hasMethod('onSearchSort')) {
             $this->sorters[$plugin->name] = $refl->getMethod('onSearchSort');
         }
     }
     // Loop the plugins once more now that we have an exhaustive list of plugin types
     $plugin_types = array_keys($weighters);
     foreach ($plugins as $plugin) {
         if (!Plugin::isEnabled('search', $plugin->name)) {
             continue;
         }
         $class = "plgSearch{$plugin->name}";
         $refl = new ReflectionClass($class);
         if ($refl->hasMethod('onSearchWeightAll')) {
             $weighters['all'][] = array($plugin->name, $refl->getMethod('onSearchWeightAll'));
         }
         foreach ($plugin_types as $type) {
             if ($refl->hasMethod("onSearchWeight{$type}")) {
                 $weighters[$type][] = array($plugin->name, $refl->getMethod("onSearchWeight{$type}"));
             }
         }
     }
     $this->current_plugin = NULL;
     $this->highlighter = $this->terms->get_word_regex();
     foreach ($this->results as $res) {
         $this->process_result($res);
     }
     // call weighters
     $any_all_weighters = !!count($weighters['all']);
     @(list($term_plugin, $term_section) = $this->terms->get_section());
     $flat_results = $this->processed_results;
     foreach ($flat_results as $res) {
         $fc_child_flag = 'plgSearch' . $res->get_plugin() . '::FIRST_CLASS_CHILDREN';
         if (!defined($fc_child_flag) || constant($fc_child_flag)) {
             foreach ($res->get_children() as $child) {
                 $flat_results[] = $child;
             }
         }
     }
     foreach ($flat_results as $res) {
         $plugin = $res->get_plugin();
         $this->result_counts[$plugin]['count']++;
         if ((!$term_plugin || $term_plugin == $plugin) && (!$term_section || $term_section == $res->get_section_key())) {
             if (array_key_exists($plugin, self::$plugin_weights)) {
                 $res->adjust_weight(self::$plugin_weights[$plugin], $plugin . ' base weight');
             }
             $used = array();
             foreach (array_key_exists($plugin, $weighters) ? array_merge($weighters['all'], $weighters[$plugin]) : $weighters['all'] as $weight_plugin) {
                 list($name, $mtd) = $weight_plugin;
                 if (!array_key_exists($name, $used)) {
                     $used[$name] = true;
                     $adj = 2 * $mtd->invokeArgs(NULL, array($this->terms, &$res));
                     if (array_key_exists($name, self::$plugin_weights)) {
                         // adj is 0..1
                         // weight is 0..1
                         $adj *= 0.5 + self::$plugin_weights[$name];
                     }
                     $res->adjust_weight($adj, $name);
                 }
             }
             $this->shown_results[] = $res;
         }
     }
     usort($this->shown_results, array($this, 'sort_results'));
     $links = array();
     foreach ($this->shown_results as $res) {
         $links[] = array(spl_object_hash($res), $res->has_parent(), $res->get_links());
     }
     $link_map = array();
     foreach ($links as $row) {
         list($id, $has_parent, $rlinks) = $row;
         foreach ($rlinks as $link) {
             if (array_key_exists($id, $link_map)) {
                 $link_map[$link] = array(array($id, $has_parent));
             } else {
                 $link_map[$link][] = array($id, $has_parent);
             }
         }
     }
     $dont_show_because_nested_elsewhere = array();
     foreach ($link_map as $rows) {
         if (count($rows) > 0) {
             foreach ($rows as $row) {
                 list($id, $has_parent) = $row;
                 if ($has_parent) {
                     $dont_show_because_nested_elsewhere[$id] = 1;
                 }
             }
         }
     }
     $this->total_count = count($this->processed_results);
     foreach ($this->shown_results as $idx => $res) {
         if (array_key_exists(spl_object_hash($res), $dont_show_because_nested_elsewhere)) {
             unset($this->shown_results[$idx]);
             ++$this->total_count;
         }
     }
     if ($this->custom) {
         # remove dupes
         $custom_links = array();
         foreach ($this->custom as $custom) {
             $plugin = $custom->get_plugin();
             $this->result_counts[$plugin]['count']++;
             $custom->highlight($this->highlighter);
             $custom_links[$custom->get_link()] = $custom->get_link();
         }
         foreach ($this->shown_results as $idx => $res) {
             if (array_key_exists($res->get_link(), $custom_links)) {
                 unset($this->shown_results[$idx]);
                 --$this->result_counts[$res->get_plugin()]['count'];
                 --$this->total_count;
             }
         }
         # prepend custom results
         $this->shown_results = array_merge($this->custom, $this->shown_results);
         $this->total_count += count($this->custom);
     }
     // Copy counts to list counts, which track how many actual <li> worth of
     // search results there are.
     //
     // The actual result counts may be higher, because some will be shown as
     // nested hierarchies of results in a single <li>, ie for courses that
     // all part of the same series.
     $this->total_list_count = $this->total_count;
     foreach ($this->result_counts as $plugin => $def) {
         $this->result_counts[$plugin]['list_count'] = $this->result_counts[$plugin]['count'];
     }
     // determine section counts and adjust plugin counts to account for
     // folded-together results
     foreach ($this->processed_results as $parent) {
         $plugin = $parent->get_plugin();
         $ccount = count($parent->get_children());
         $this->total_list_count -= $ccount;
         $this->result_counts[$plugin]['list_count'] -= $ccount;
         if (!array_key_exists('sections', $this->result_counts[$plugin])) {
             $this->result_counts[$plugin]['sections'] = array();
         }
         foreach (array_merge(array($parent), $parent->get_children()) as $idx => $res) {
             if ($idx > 0) {
                 --$this->total_list_count;
                 --$this->result_counts[$plugin]['list_count'];
             }
             $section = $res->get_section();
             if (!trim($section)) {
                 $section = 'Uncategorized';
             }
             $section_key = strtolower(str_replace(' ', '_', trim($section)));
             if (!array_key_exists($section_key, $this->result_counts[$plugin]['sections'])) {
                 $this->result_counts[$plugin]['sections'][$section_key] = array('name' => $section, 'count' => 1);
             } else {
                 ++$this->result_counts[$plugin]['sections'][$section_key]['count'];
             }
         }
     }
     // Recalculate the totals
     // [CDMHUB][#1034]
     $total = 0;
     foreach ($this->result_counts as $plugin => $def) {
         $total += $this->result_counts[$plugin]['count'];
     }
     $this->total_list_count = $this->total_count = $total;
     if ($this->limit > 0) {
         $this->shown_results = array_slice($this->shown_results, $this->offset, $this->limit);
     }
 }