Example #1
0
 /**
  * Parse a plugin tag pair equivalent to channel:entries
  *
  * @param  Closure|null $callback receieves a query builder object as the first parameter
  * @return string
  */
 public function parseEntries(Closure $callback = null)
 {
     $entries = $this->getEntries($callback);
     $output = $this->parseEntryCollection($entries, ee()->TMPL->tagdata, ee()->TMPL->tagparams, ee()->TMPL->var_pair, ee()->TMPL->var_single);
     if ($this->paginator->paginate) {
         $output = $this->paginator->render($output);
     }
     return $output;
 }
 /** ----------------------------------------
 	/**  Show search results
 	/** ----------------------------------------*/
 function search_results()
 {
     // Fetch the search language file
     $this->EE->lang->loadfile('search');
     // Load Pagination Object
     $this->EE->load->library('pagination');
     $pagination = new Pagination_object(__CLASS__);
     // Capture Pagination Template
     $pagination->get_template();
     // Check to see if we're using old style pagination
     // TODO: Remove once old pagination is phased out
     $old_pagination = strpos($this->EE->TMPL->template, LD . 'if paginate' . RD) !== FALSE ? TRUE : FALSE;
     // If we are using old pagination, log it as deprecated
     // TODO: Remove once old pagination is phased out
     if ($old_pagination) {
         $this->EE->load->library('logger');
         $this->EE->logger->developer('Deprecated template tag {if paginate}. Old style pagination in the Search Module has been deprecated in 2.4 and will be removed soon. Switch to the new Channel style pagination.', TRUE);
     }
     // Check search ID number
     // If the QSTR variable is less than 32 characters long we
     // don't have a valid search ID number
     if (strlen($this->EE->uri->query_string) < 32) {
         return $this->EE->output->show_user_error('off', array(lang('search_no_result')), lang('search_result_heading'));
     }
     // Clear old search results
     $this->EE->db->delete('search', array('site_id' => $this->EE->config->item('site_id'), 'search_date <' => $this->EE->localize->now - $this->cache_expire * 3600));
     // Fetch ID number and page number
     $pagination->offset = 0;
     $qstring = $this->EE->uri->query_string;
     // Parse page number
     if (preg_match("#^P(\\d+)|/P(\\d+)#", $qstring, $match)) {
         $pagination->offset = isset($match[2]) ? $match[2] : $match[1];
         $search_id = trim_slashes(str_replace($match[0], '', $qstring));
     } else {
         $pagination->offset = 0;
         $search_id = $qstring;
     }
     // If there is a slash in the search ID we'll kill everything after it.
     $search_id = trim($search_id);
     $search_id = preg_replace("#/.+#", "", $search_id);
     // Fetch the cached search query
     $query = $this->EE->db->get_where('search', array('search_id' => $search_id));
     if ($query->num_rows() == 0 or $query->row('total_results') == 0) {
         return $this->EE->output->show_user_error('off', array(lang('search_no_result')), lang('search_result_heading'));
     }
     $fields = $query->row('custom_fields') == '' ? array() : unserialize(stripslashes($query->row('custom_fields')));
     $sql = unserialize(stripslashes($query->row('query')));
     $sql = str_replace('MDBMPREFIX', 'exp_', $sql);
     $pagination->per_page = (int) $query->row('per_page');
     $res_page = $query->row('result_page');
     // Run the search query
     $query = $this->EE->db->query(preg_replace("/SELECT(.*?)\\s+FROM\\s+/is", 'SELECT COUNT(*) AS count FROM ', $sql));
     if ($query->row('count') == 0) {
         return $this->EE->output->show_user_error('off', array(lang('search_no_result')), lang('search_result_heading'));
     }
     // Calculate total number of pages and add total rows
     $pagination->current_page = $pagination->offset / $pagination->per_page + 1;
     $pagination->total_rows = $query->row('count');
     // Figure out total number of pages for old style pagination
     // TODO: Remove once old pagination is phased out
     if ($old_pagination) {
         $total_pages = intval($pagination->total_rows / $pagination->per_page);
         if ($pagination->total_rows % $pagination->per_page) {
             $total_pages++;
         }
         $page_count = lang('page') . ' ' . $pagination->current_page . ' ' . lang('of') . ' ' . $total_pages;
         $pager = '';
         if ($pagination->total_rows > $pagination->per_page) {
             $this->EE->load->library('pagination');
             $config = array('base_url' => $this->EE->functions->create_url($res_page . '/' . $search_id, 0, 0), 'prefix' => 'P', 'total_rows' => $pagination->total_rows, 'per_page' => $pagination->per_page, 'cur_page' => $pagination->offset, 'first_link' => lang('pag_first_link'), 'last_link' => lang('pag_last_link'), 'uri_segment' => 0);
             $this->EE->pagination->initialize($config);
             $pager = $this->EE->pagination->create_links();
         }
     }
     // Build pagination if enabled
     if ($pagination->paginate === TRUE) {
         $pagination->build($pagination->total_rows);
     }
     // If we're paginating, old or new, limit the query and do it again
     if ($pagination->paginate === TRUE or $old_pagination) {
         $sql .= " LIMIT " . $pagination->offset . ", " . $pagination->per_page;
     } else {
         if ($pagination->per_page > 0) {
             $sql .= " LIMIT 0, " . $pagination->per_page;
         } else {
             $sql .= " LIMIT 0, 100";
         }
     }
     $query = $this->EE->db->query($sql);
     $output = '';
     if (!class_exists('Channel')) {
         require PATH_MOD . 'channel/mod.channel.php';
     }
     unset($this->EE->TMPL->var_single['auto_path']);
     unset($this->EE->TMPL->var_single['excerpt']);
     unset($this->EE->TMPL->var_single['id_auto_path']);
     unset($this->EE->TMPL->var_single['full_text']);
     unset($this->EE->TMPL->var_single['switch']);
     foreach ($this->EE->TMPL->var_single as $key => $value) {
         if (substr($key, 0, strlen('member_path')) == 'member_path') {
             unset($this->EE->TMPL->var_single[$key]);
         }
     }
     $channel = new Channel();
     // This allows the channel {absolute_count} variable to work
     $channel->pagination->offset = $pagination->per_page * $pagination->current_page - $pagination->per_page;
     $channel->fetch_custom_channel_fields();
     $channel->fetch_custom_member_fields();
     $channel->query = $this->EE->db->query($sql);
     if ($channel->query->num_rows() == 0) {
         return $this->EE->TMPL->no_results();
     }
     $this->EE->load->library('typography');
     $this->EE->typography->initialize(array('convert_curly' => FALSE, 'encode_email' => FALSE));
     $channel->fetch_categories();
     $channel->parse_channel_entries();
     $tagdata = $this->EE->TMPL->tagdata;
     // Does the tag contain "related entries" that we need to parse out?
     if (count($this->EE->TMPL->related_data) > 0 and count($channel->related_entries) > 0) {
         $channel->parse_related_entries();
     }
     if (count($this->EE->TMPL->reverse_related_data) > 0 and count($channel->reverse_related_entries) > 0) {
         $channel->parse_reverse_related_entries();
     }
     $output = $channel->return_data;
     $this->EE->TMPL->tagdata = $tagdata;
     // Fetch member path variable
     // We do it here in case it's used in multiple places.
     $m_paths = array();
     if (preg_match_all("/" . LD . "member_path(\\s*=.*?)" . RD . "/s", $this->EE->TMPL->tagdata, $matches)) {
         for ($j = 0; $j < count($matches['0']); $j++) {
             $m_paths[] = array($matches['0'][$j], $this->EE->functions->extract_path($matches['1'][$j]));
         }
     }
     // Fetch switch param
     $switch1 = '';
     $switch2 = '';
     if ($switch = $this->EE->TMPL->fetch_param('switch')) {
         if (strpos($switch, '|') !== FALSE) {
             $x = explode("|", $switch);
             $switch1 = $x['0'];
             $switch2 = $x['1'];
         } else {
             $switch1 = $switch;
         }
     }
     /** -----------------------------
     		/**  Result Loop - Legacy!
     		/** -----------------------------*/
     $i = 0;
     foreach ($query->result_array() as $row) {
         if (isset($row['field_id_' . $row['search_excerpt']]) and $row['field_id_' . $row['search_excerpt']]) {
             $format = !isset($row['field_ft_' . $row['search_excerpt']]) ? 'xhtml' : $row['field_ft_' . $row['search_excerpt']];
             $full_text = $this->EE->typography->parse_type(strip_tags($row['field_id_' . $row['search_excerpt']]), array('text_format' => $format, 'html_format' => 'safe', 'auto_links' => 'y', 'allow_img_url' => 'n'));
             $excerpt = trim(strip_tags($full_text));
             if (strpos($excerpt, "\r") !== FALSE or strpos($excerpt, "\n") !== FALSE) {
                 $excerpt = str_replace(array("\r\n", "\r", "\n"), " ", $excerpt);
             }
             $excerpt = $this->EE->functions->word_limiter($excerpt, 50);
         } else {
             $excerpt = '';
             $full_text = '';
         }
         // Parse permalink path
         $url = $row['search_results_url'] != '' ? $row['search_results_url'] : $row['channel_url'];
         $path = $this->EE->functions->remove_double_slashes($this->EE->functions->prep_query_string($url) . '/' . $row['url_title']);
         $idpath = $this->EE->functions->remove_double_slashes($this->EE->functions->prep_query_string($url) . '/' . $row['entry_id']);
         $switch = $i++ % 2 ? $switch1 : $switch2;
         $output = preg_replace("/" . LD . 'switch' . RD . "/", $switch, $output, count(explode(LD . 'switch' . RD, $this->EE->TMPL->tagdata)) - 1);
         $output = preg_replace("/" . LD . 'auto_path' . RD . "/", $path, $output, count(explode(LD . 'auto_path' . RD, $this->EE->TMPL->tagdata)) - 1);
         $output = preg_replace("/" . LD . 'id_auto_path' . RD . "/", $idpath, $output, count(explode(LD . 'id_auto_path' . RD, $this->EE->TMPL->tagdata)) - 1);
         $output = preg_replace("/" . LD . 'excerpt' . RD . "/", preg_quote($excerpt), $output, count(explode(LD . 'excerpt' . RD, $this->EE->TMPL->tagdata)) - 1);
         $output = preg_replace("/" . LD . 'full_text' . RD . "/", preg_quote($full_text), $output, count(explode(LD . 'full_text' . RD, $this->EE->TMPL->tagdata)) - 1);
         // Parse member_path
         if (count($m_paths) > 0) {
             foreach ($m_paths as $val) {
                 $output = preg_replace("/" . preg_quote($val['0'], '/') . "/", $this->EE->functions->create_url($val['1'] . '/' . $row['member_id']), $output, 1);
             }
         }
     }
     $this->EE->TMPL->tagdata = $output;
     // Add new pagination
     $this->EE->TMPL->tagdata = $pagination->render($this->EE->TMPL->tagdata);
     // Parse lang variables
     $swap = array('lang:total_search_results' => lang('search_total_results'), 'lang:search_engine' => lang('search_engine'), 'lang:search_results' => lang('search_results'), 'lang:search' => lang('search'), 'lang:title' => lang('search_title'), 'lang:channel' => lang('search_channel'), 'lang:excerpt' => lang('search_excerpt'), 'lang:author' => lang('search_author'), 'lang:date' => lang('search_date'), 'lang:total_comments' => lang('search_total_comments'), 'lang:recent_comments' => lang('search_recent_comment_date'), 'lang:keywords' => lang('search_keywords'));
     $this->EE->TMPL->template = $this->EE->functions->var_swap($this->EE->TMPL->template, $swap);
     // Add Old Style Pagination
     // TODO: Remove once old pagination is phased out
     if ($old_pagination) {
         if ($pager == '') {
             $this->EE->TMPL->template = preg_replace("#" . LD . "if paginate" . RD . ".*?" . LD . "/if" . RD . "#s", '', $this->EE->TMPL->template);
         } else {
             $this->EE->TMPL->template = preg_replace("#" . LD . "if paginate" . RD . "(.*?)" . LD . "/if" . RD . "#s", "\\1", $this->EE->TMPL->template);
         }
         $this->EE->TMPL->template = str_replace(LD . 'paginate' . RD, $pager, $this->EE->TMPL->template);
         $this->EE->TMPL->template = str_replace(LD . 'page_count' . RD, $page_count, $this->EE->TMPL->template);
     }
     return $this->EE->TMPL->tagdata;
 }
    /**
     * Comment Entries
     *
     * @access	public
     * @return	string
     */
    public function entries()
    {
        $return = '';
        $qstring = ee()->uri->query_string;
        $uristr = ee()->uri->uri_string;
        $switch = array();
        $search_link = '';
        $enabled = $this->_fetch_disable_param();
        if ($enabled['pagination']) {
            ee()->load->library('pagination');
            $pagination = new Pagination_object(__CLASS__);
        }
        if (ee()->TMPL->fetch_param('dynamic') == 'no') {
            $dynamic = FALSE;
        } else {
            $dynamic = TRUE;
        }
        //
        $force_entry = FALSE;
        if (ee()->TMPL->fetch_param('author_id') !== FALSE or ee()->TMPL->fetch_param('entry_id') !== FALSE or ee()->TMPL->fetch_param('url_title') !== FALSE or ee()->TMPL->fetch_param('comment_id') !== FALSE) {
            $force_entry = TRUE;
        }
        // A note on returns!
        // If dynamic is off - ANY no results triggers no_result template
        // If dynamic is on- we do not want to trigger no_results on a non-single entry page
        // so only trigger if no comment ids- not for no valid entry ids existing
        // Do not vary by force_entry setting
        /** ----------------------------------------------
        		/**  Do we allow dynamic POST variables to set parameters?
        		/** ----------------------------------------------*/
        if (ee()->TMPL->fetch_param('dynamic_parameters') !== FALSE and isset($_POST) and count($_POST) > 0) {
            foreach (explode('|', ee()->TMPL->fetch_param('dynamic_parameters')) as $var) {
                if (isset($_POST[$var]) and in_array($var, array('channel', 'limit', 'sort', 'orderby'))) {
                    ee()->TMPL->tagparams[$var] = $_POST[$var];
                }
            }
        }
        /** --------------------------------------
        		/**  Parse page number
        		/** --------------------------------------*/
        // We need to strip the page number from the URL for two reasons:
        // 1. So we can create pagination links
        // 2. So it won't confuse the query with an improper proper ID
        if (!$dynamic) {
            if (preg_match("#(^|/)N(\\d+)(/|\$)#i", $qstring, $match)) {
                if ($enabled['pagination']) {
                    $pagination->current_page = $match['2'];
                }
                $uristr = trim(reduce_double_slashes(str_replace($match['0'], '/', $uristr)), '/');
            }
        } else {
            if (preg_match("#(^|/)P(\\d+)(/|\$)#", $qstring, $match)) {
                if ($enabled['pagination']) {
                    $pagination->current_page = $match['2'];
                }
                $uristr = reduce_double_slashes(str_replace($match['0'], '/', $uristr));
                $qstring = trim(reduce_double_slashes(str_replace($match['0'], '/', $qstring)), '/');
            }
        }
        // Fetch channel_ids if appropriate
        $channel_ids = array();
        if ($channel = ee()->TMPL->fetch_param('channel') or ee()->TMPL->fetch_param('site')) {
            ee()->db->select('channel_id');
            ee()->db->where_in('site_id', ee()->TMPL->site_ids);
            if ($channel !== FALSE) {
                ee()->functions->ar_andor_string($channel, 'channel_name');
            }
            $channels = ee()->db->get('channels');
            if ($channels->num_rows() == 0) {
                if (!$dynamic) {
                    return ee()->TMPL->no_results();
                }
                return false;
            } else {
                foreach ($channels->result_array() as $row) {
                    $channel_ids[] = $row['channel_id'];
                }
            }
        }
        // Fetch entry ids- we'll use them to make sure comments are to open, etc. entries
        $comment_id_param = FALSE;
        if ($dynamic == TRUE or $force_entry == TRUE) {
            if ($force_entry == TRUE) {
                // Check if an entry_id, url_title or comment_id was specified
                if ($entry_id = ee()->TMPL->fetch_param('entry_id')) {
                    ee()->functions->ar_andor_string($entry_id, 'entry_id');
                } elseif ($url_title = ee()->TMPL->fetch_param('url_title')) {
                    ee()->functions->ar_andor_string($url_title, 'url_title');
                } elseif ($comment_id_param = ee()->TMPL->fetch_param('comment_id')) {
                    $force_entry_ids = $this->fetch_comment_ids_param($comment_id_param);
                    if (count($force_entry_ids) == 0) {
                        // No entry ids for the comment ids?  How'd they manage that
                        if (!$dynamic) {
                            return ee()->TMPL->no_results();
                        }
                        return false;
                    }
                    ee()->db->where_in('entry_id', $force_entry_ids);
                }
            } else {
                // If there is a slash in the entry ID we'll kill everything after it.
                $entry_id = trim($qstring);
                $entry_id = preg_replace("#/.+#", "", $entry_id);
                // Have to choose between id or url title
                if (!is_numeric($entry_id)) {
                    ee()->db->where('url_title', $entry_id);
                } else {
                    ee()->db->where('entry_id', $entry_id);
                }
            }
            //  Do we have a valid entry ID number?
            $timestamp = ee()->TMPL->cache_timestamp != '' ? ee()->TMPL->cache_timestamp : ee()->localize->now;
            ee()->db->select('entry_id, channel_id');
            //ee()->db->where('channel_titles.channel_id = '.ee()->db->dbprefix('channels').'.channel_id');
            ee()->db->where_in('channel_titles.site_id', ee()->TMPL->site_ids);
            if (ee()->TMPL->fetch_param('show_expired') !== 'yes') {
                $date_where = "(" . ee()->db->protect_identifiers('expiration_date') . " = 0 OR " . ee()->db->protect_identifiers('expiration_date') . " > {$timestamp})";
                ee()->db->where($date_where);
            }
            if ($e_status = ee()->TMPL->fetch_param('entry_status')) {
                $e_status = str_replace('Open', 'open', $e_status);
                $e_status = str_replace('Closed', 'closed', $e_status);
                // If they don't specify closed, it defaults to it
                if (!in_array('closed', explode('|', $e_status))) {
                    ee()->db->where('status !=', 'closed');
                }
                ee()->functions->ar_andor_string($e_status, 'status');
            } else {
                ee()->db->where('status !=', 'closed');
            }
            //  Limit to/exclude specific channels
            if (count($channel_ids) == 1) {
                ee()->db->where('channel_titles.channel_id', $channel_ids['0']);
            } elseif (count($channel_ids) > 1) {
                ee()->db->where_in('channel_titles.channel_id', $channel_ids);
            }
            ee()->db->from('channel_titles');
            $query = ee()->db->get();
            // Bad ID?  See ya!
            if ($query->num_rows() == 0) {
                if (!$dynamic) {
                    return ee()->TMPL->no_results();
                }
                return false;
            }
            // We'll reassign the entry IDs so they're the true numeric ID
            foreach ($query->result_array() as $row) {
                $entry_ids[] = $row['entry_id'];
            }
        }
        //  Set sorting and limiting
        if (!$dynamic) {
            if ($enabled['pagination']) {
                $pagination->per_page = ee()->TMPL->fetch_param('limit', 100);
            } else {
                $limit = ee()->TMPL->fetch_param('limit', 100);
            }
            $sort = ee()->TMPL->fetch_param('sort', 'desc');
        } else {
            if ($enabled['pagination']) {
                $pagination->per_page = ee()->TMPL->fetch_param('limit', $this->limit);
            } else {
                $limit = ee()->TMPL->fetch_param('limit', $this->limit);
            }
            $sort = ee()->TMPL->fetch_param('sort', 'asc');
        }
        $allowed_sorts = array('date', 'email', 'location', 'name', 'url');
        if ($enabled['pagination']) {
            // Capture the pagination template
            $pagination->get_template();
        }
        /** ----------------------------------------
        		/**  Fetch comment ID numbers
        		/** ----------------------------------------*/
        $temp = array();
        $i = 0;
        // Left this here for backward compatibility
        // We need to deprecate the "order_by" parameter
        if (ee()->TMPL->fetch_param('orderby') != '') {
            $order_by = ee()->TMPL->fetch_param('orderby');
        } else {
            $order_by = ee()->TMPL->fetch_param('order_by');
        }
        $random = $order_by == 'random' ? TRUE : FALSE;
        $order_by = ($order_by == 'date' or !in_array($order_by, $allowed_sorts)) ? 'comment_date' : $order_by;
        // We cache the query in case we need to do a count for dynamic off pagination
        ee()->db->start_cache();
        ee()->db->select('comment_date, comment_id');
        ee()->db->from('comments c');
        if ($status = ee()->TMPL->fetch_param('status')) {
            $status = strtolower($status);
            $status = str_replace('open', 'o', $status);
            $status = str_replace('closed', 'c', $status);
            $status = str_replace('pending', 'p', $status);
            ee()->functions->ar_andor_string($status, 'c.status');
            // No custom status for comments, so we can be leaner in check for 'c'
            if (stristr($status, "c") === FALSE) {
                ee()->db->where('c.status !=', 'c');
            }
        } else {
            ee()->db->where('c.status', 'o');
        }
        if ($author_id = ee()->TMPL->fetch_param('author_id')) {
            ee()->db->where('c.author_id', $author_id);
        }
        // Note if it's not dynamic and the entry isn't forced?  We don't check on the entry criteria,
        // so this point, dynamic and forced entry will have 'valid' entry ids, dynamic off may not
        if (!$dynamic && !$force_entry) {
            //  Limit to/exclude specific channels
            if (count($channel_ids) == 1) {
                ee()->db->where('c.channel_id', $channel_ids['0'], FALSE);
            } elseif (count($channel_ids) > 1) {
                ee()->db->where_in('c.channel_id', $channel_ids);
            }
            ee()->db->join('channel_titles ct', 'ct.entry_id = c.entry_id');
            if ($e_status = ee()->TMPL->fetch_param('entry_status')) {
                $e_status = str_replace('Open', 'open', $e_status);
                $e_status = str_replace('Closed', 'closed', $e_status);
                // If they don't specify closed, it defaults to it
                if (!in_array('closed', explode('|', $e_status))) {
                    ee()->db->where('ct.status !=', 'closed');
                }
                ee()->functions->ar_andor_string($e_status, 'ct.status');
            } else {
                ee()->db->where('ct.status !=', 'closed');
            }
            // seems redundant given channels
            ee()->db->where_in('c.site_id', ee()->TMPL->site_ids, FALSE);
            if (ee()->TMPL->fetch_param('show_expired') !== 'yes') {
                $timestamp = ee()->TMPL->cache_timestamp != '' ? ee()->TMPL->cache_timestamp : ee()->localize->now;
                $date_where = "(" . ee()->db->protect_identifiers('ct.expiration_date') . " = 0 OR " . ee()->db->protect_identifiers('ct.expiration_date') . " > {$timestamp})";
                ee()->db->where($date_where);
            }
        } else {
            // Force entry may result in multiple entry ids
            if (isset($entry_ids) && count($entry_ids) > 0) {
                ee()->db->where_in('c.entry_id', $entry_ids);
            } else {
                ee()->db->where('c.entry_id', $entry_id);
            }
            if ($comment_id_param) {
                ee()->functions->ar_andor_string($comment_id_param, 'comment_id');
            }
        }
        if ($enabled['pagination']) {
            $total_rows = ee()->db->count_all_results();
            if ($pagination->paginate === TRUE) {
                // When we are only showing comments and it is
                // not based on an entry id or url title
                // in the URL, we can make the query much
                // more efficient and save some work.
                $pagination->total_rows = $total_rows;
            }
        }
        $this_sort = $random ? 'random' : strtolower($sort);
        // We're not stripping it out this time, so we can just
        // ignore the check if we're not paginating.
        if ($enabled['pagination']) {
            $p = !$dynamic ? 'N' : 'P';
            // Figure out of we need a pagination offset
            if (preg_match('/' . $p . '(\\d+)(?:\\/|$)/', ee()->uri->uri_string, $matches)) {
                $pagination->offset = $matches[1];
            } else {
                $pagination->offset = 0;
            }
        }
        ee()->db->order_by($order_by, $this_sort);
        if ($enabled['pagination']) {
            ee()->db->limit($pagination->per_page, $pagination->offset);
        } else {
            ee()->db->limit($limit, 0);
        }
        ee()->db->stop_cache();
        $query = ee()->db->get();
        ee()->db->flush_cache();
        $result_ids = array();
        if ($query->num_rows() > 0) {
            foreach ($query->result() as $row) {
                $result_ids[] = $row->comment_id;
            }
        }
        //  No results?  No reason to continue...
        if (count($result_ids) == 0) {
            return ee()->TMPL->no_results();
        }
        if ($enabled['pagination']) {
            // Build pagination
            $pagination->build($pagination->per_page);
        }
        /** -----------------------------------
        		/**  Fetch Comments if necessary
        		/** -----------------------------------*/
        $results = $result_ids;
        $mfields = array();
        /** ----------------------------------------
        		/**  "Search by Member" link
        		/** ----------------------------------------*/
        // We use this with the {member_search_path} variable
        $result_path = preg_match("/" . LD . "member_search_path\\s*=(.*?)" . RD . "/s", ee()->TMPL->tagdata, $match) ? $match['1'] : 'search/results';
        $result_path = str_replace("\"", "", $result_path);
        $result_path = str_replace("'", "", $result_path);
        $search_link = ee()->functions->fetch_site_index(0, 0) . QUERY_MARKER . 'ACT=' . ee()->functions->fetch_action_id('Search', 'do_search') . '&amp;result_path=' . $result_path . '&amp;mbr=';
        ee()->db->select('comments.comment_id, comments.entry_id, comments.channel_id, comments.author_id, comments.name, comments.email, comments.url, comments.location AS c_location, comments.ip_address, comments.comment_date, comments.edit_date, comments.comment, comments.site_id AS comment_site_id,
			members.username, members.group_id, members.location, members.occupation, members.interests, members.aol_im, members.yahoo_im, members.msn_im, members.icq, members.group_id, members.member_id, members.signature, members.sig_img_filename, members.sig_img_width, members.sig_img_height, members.avatar_filename, members.avatar_width, members.avatar_height, members.photo_filename, members.photo_width, members.photo_height,
			member_data.*,
			channel_titles.title, channel_titles.url_title, channel_titles.author_id AS entry_author_id,
			channels.comment_text_formatting, channels.comment_html_formatting, channels.comment_allow_img_urls, channels.comment_auto_link_urls, channels.channel_url, channels.comment_url, channels.channel_title, channels.channel_name AS channel_short_name');
        ee()->db->join('channels', 'comments.channel_id = channels.channel_id', 'left');
        ee()->db->join('channel_titles', 'comments.entry_id = channel_titles.entry_id', 'left');
        ee()->db->join('members', 'members.member_id = comments.author_id', 'left');
        ee()->db->join('member_data', 'member_data.member_id = members.member_id', 'left');
        ee()->db->where_in('comments.comment_id', $result_ids);
        ee()->db->order_by($order_by, $this_sort);
        $query = ee()->db->get('comments');
        $total_results = $query->num_rows();
        if ($query->num_rows() > 0) {
            $results = $query->result_array();
            // Potentially a lot of information
            $query->free_result();
        }
        /** ----------------------------------------
        		/**  Fetch custom member field IDs
        		/** ----------------------------------------*/
        ee()->db->select('m_field_id, m_field_name');
        $query = ee()->db->get('member_fields');
        if ($query->num_rows() > 0) {
            foreach ($query->result_array() as $row) {
                $mfields[$row['m_field_name']] = $row['m_field_id'];
            }
        }
        /** ----------------------------------------
        		/**  Instantiate Typography class
        		/** ----------------------------------------*/
        ee()->load->library('typography');
        ee()->typography->initialize(array('parse_images' => FALSE, 'allow_headings' => FALSE, 'word_censor' => ee()->config->item('comment_word_censoring') == 'y' ? TRUE : FALSE));
        /** ----------------------------------------
        		/**  Fetch all the date-related variables
        		/** ----------------------------------------*/
        $gmt_comment_date = array();
        $comment_date = array();
        $edit_date = array();
        // We do this here to avoid processing cycles in the foreach loop
        $date_vars = array('gmt_comment_date', 'comment_date', 'edit_date');
        foreach ($date_vars as $val) {
            if (preg_match_all("/" . LD . $val . "\\s+format=[\"'](.*?)[\"']" . RD . "/s", ee()->TMPL->tagdata, $matches)) {
                for ($j = 0; $j < count($matches['0']); $j++) {
                    $matches['0'][$j] = str_replace(LD, '', $matches['0'][$j]);
                    $matches['0'][$j] = str_replace(RD, '', $matches['0'][$j]);
                    switch ($val) {
                        case 'comment_date':
                            $comment_date[$matches['0'][$j]] = $matches['1'][$j];
                            break;
                        case 'gmt_comment_date':
                            $gmt_comment_date[$matches['0'][$j]] = $matches['1'][$j];
                            break;
                        case 'edit_date':
                            $edit_date[$matches['0'][$j]] = $matches['1'][$j];
                            break;
                    }
                }
            }
        }
        /** ----------------------------------------
        		/**  Protected Variables for Cleanup Routine
        		/** ----------------------------------------*/
        // Since comments do not necessarily require registration, and since
        // you are allowed to put member variables in comments, we need to kill
        // left-over unparsed junk.  The $member_vars array is all of those
        // member related variables that should be removed.
        $member_vars = array('location', 'occupation', 'interests', 'aol_im', 'yahoo_im', 'msn_im', 'icq', 'signature', 'sig_img_filename', 'sig_img_width', 'sig_img_height', 'avatar_filename', 'avatar_width', 'avatar_height', 'photo_filename', 'photo_width', 'photo_height');
        $member_cond_vars = array();
        foreach ($member_vars as $var) {
            $member_cond_vars[$var] = '';
        }
        /** ----------------------------------------
        		/**  Start the processing loop
        		/** ----------------------------------------*/
        $item_count = 0;
        $relative_count = 0;
        if ($enabled['pagination']) {
            $absolute_count = $pagination->current_page == '' ? 0 : ($pagination->current_page - 1) * $pagination->per_page;
        } else {
            $absolute_count = 0;
        }
        foreach ($results as $id => $row) {
            if (!is_array($row)) {
                continue;
            }
            $relative_count++;
            $absolute_count++;
            $row['count'] = $relative_count;
            $row['absolute_count'] = $absolute_count;
            if ($enabled['pagination']) {
                $row['total_comments'] = $total_rows;
            }
            $row['total_results'] = $total_results;
            // This lets the {if location} variable work
            if (isset($row['author_id'])) {
                if ($row['author_id'] == 0) {
                    $row['location'] = $row['c_location'];
                }
            }
            $tagdata = ee()->TMPL->tagdata;
            // -------------------------------------------
            // 'comment_entries_tagdata' hook.
            //  - Modify and play with the tagdata before everyone else
            //
            if (ee()->extensions->active_hook('comment_entries_tagdata') === TRUE) {
                $tagdata = ee()->extensions->call('comment_entries_tagdata', $tagdata, $row);
                if (ee()->extensions->end_script === TRUE) {
                    return $tagdata;
                }
            }
            //
            // -------------------------------------------
            /** ----------------------------------------
            			/**  Conditionals
            			/** ----------------------------------------*/
            $cond = array_merge($member_cond_vars, $row);
            $cond['comments'] = substr($id, 0, 1) == 't' ? 'FALSE' : 'TRUE';
            $cond['logged_in'] = ee()->session->userdata('member_id') == 0 ? 'FALSE' : 'TRUE';
            $cond['logged_out'] = ee()->session->userdata('member_id') != 0 ? 'FALSE' : 'TRUE';
            $cond['allow_comments'] = (isset($row['allow_comments']) and $row['allow_comments'] == 'n') ? 'FALSE' : 'TRUE';
            $cond['signature_image'] = (!isset($row['sig_img_filename']) or $row['sig_img_filename'] == '' or ee()->config->item('enable_signatures') == 'n' or ee()->session->userdata('display_signatures') == 'n') ? 'FALSE' : 'TRUE';
            $cond['avatar'] = (!isset($row['avatar_filename']) or $row['avatar_filename'] == '' or ee()->config->item('enable_avatars') == 'n' or ee()->session->userdata('display_avatars') == 'n') ? 'FALSE' : 'TRUE';
            $cond['photo'] = (!isset($row['photo_filename']) or $row['photo_filename'] == '' or ee()->config->item('enable_photos') == 'n' or ee()->session->userdata('display_photos') == 'n') ? 'FALSE' : 'TRUE';
            $cond['is_ignored'] = (!isset($row['member_id']) or !in_array($row['member_id'], ee()->session->userdata['ignore_list'])) ? 'FALSE' : 'TRUE';
            $cond['editable'] = FALSE;
            $cond['can_moderate_comment'] = FALSE;
            if (ee()->session->userdata['group_id'] == 1 or ee()->session->userdata['can_edit_all_comments'] == 'y' or ee()->session->userdata['can_edit_own_comments'] == 'y' && $row['entry_author_id'] == ee()->session->userdata['member_id']) {
                $cond['editable'] = TRUE;
                $cond['can_moderate_comment'] = TRUE;
            } elseif (ee()->session->userdata['member_id'] != '0' && $row['author_id'] == ee()->session->userdata['member_id'] && $row['comment_date'] > $this->_comment_edit_time_limit()) {
                $cond['editable'] = TRUE;
            }
            if (isset($mfields) && is_array($mfields) && count($mfields) > 0) {
                foreach ($mfields as $key => $value) {
                    if (isset($row['m_field_id_' . $value])) {
                        $cond[$key] = $row['m_field_id_' . $value];
                    }
                }
            }
            $tagdata = ee()->functions->prep_conditionals($tagdata, $cond);
            /** ----------------------------------------
            			/**  Parse "single" variables
            			/** ----------------------------------------*/
            foreach (ee()->TMPL->var_single as $key => $val) {
                /** ----------------------------------------
                				/**  parse {switch} variable
                				/** ----------------------------------------*/
                if (strncmp($key, 'switch', 6) == 0) {
                    $sparam = ee()->functions->assign_parameters($key);
                    $sw = '';
                    if (isset($sparam['switch'])) {
                        $sopt = @explode("|", $sparam['switch']);
                        $sw = $sopt[($relative_count + count($sopt) - 1) % count($sopt)];
                    }
                    $tagdata = ee()->TMPL->swap_var_single($key, $sw, $tagdata);
                }
                /** ----------------------------------------
                				/**  parse permalink
                				/** ----------------------------------------*/
                if ($key == 'permalink' && isset($row['comment_id'])) {
                    $tagdata = ee()->TMPL->swap_var_single($key, ee()->functions->create_url($uristr . '#' . $row['comment_id'], FALSE), $tagdata);
                }
                /** ----------------------------------------
                				/**  parse comment_path
                				/** ----------------------------------------*/
                if (strncmp($key, 'comment_path', 12) == 0 or strncmp($key, 'entry_id_path', 13) == 0) {
                    $tagdata = ee()->TMPL->swap_var_single($key, ee()->functions->create_url(ee()->functions->extract_path($key) . '/' . $row['entry_id']), $tagdata);
                }
                /** ----------------------------------------
                				/**  parse title permalink
                				/** ----------------------------------------*/
                if (strncmp($key, 'title_permalink', 15) == 0 or strncmp($key, 'url_title_path', 14) == 0) {
                    $path = (ee()->functions->extract_path($key) != '' and ee()->functions->extract_path($key) != 'SITE_INDEX') ? ee()->functions->extract_path($key) . '/' . $row['url_title'] : $row['url_title'];
                    $tagdata = ee()->TMPL->swap_var_single($key, ee()->functions->create_url($path, FALSE), $tagdata);
                }
                /** ----------------------------------------
                				/**  parse comment date
                				/** ----------------------------------------*/
                if (isset($comment_date[$key]) && isset($row['comment_date'])) {
                    $tagdata = ee()->TMPL->swap_var_single($key, ee()->localize->format_date($comment_date[$key], $row['comment_date']), $tagdata);
                }
                /** ----------------------------------------
                				/**  parse GMT comment date
                				/** ----------------------------------------*/
                if (isset($gmt_comment_date[$key]) && isset($row['comment_date'])) {
                    $tagdata = ee()->TMPL->swap_var_single($key, ee()->localize->format_date($gmt_comment_date[$key], $row['comment_date'], FALSE), $tagdata);
                }
                /** ----------------------------------------
                				/**  parse "last edit" date
                				/** ----------------------------------------*/
                if (isset($edit_date[$key])) {
                    if (isset($row['edit_date'])) {
                        $tagdata = ee()->TMPL->swap_var_single($key, ee()->localize->format_date($edit_date[$key], $row['edit_date']), $tagdata);
                    }
                }
                /** ----------------------------------------
                				/**  {member_search_path}
                				/** ----------------------------------------*/
                if (strncmp($key, 'member_search_path', 18) == 0) {
                    $tagdata = ee()->TMPL->swap_var_single($key, $search_link . $row['author_id'], $tagdata);
                }
                // {member_group_id}
                if ($key == 'member_group_id') {
                    $tagdata = ee()->TMPL->swap_var_single($key, $row['group_id'], $tagdata);
                }
                // Prep the URL
                if (isset($row['url'])) {
                    ee()->load->helper('url');
                    $row['url'] = prep_url($row['url']);
                }
                /** ----------------------------------------
                				/**  {username}
                				/** ----------------------------------------*/
                if ($key == "username") {
                    $tagdata = ee()->TMPL->swap_var_single($val, isset($row['username']) ? $row['username'] : '', $tagdata);
                }
                /** ----------------------------------------
                				/**  {author}
                				/** ----------------------------------------*/
                if ($key == "author") {
                    $tagdata = ee()->TMPL->swap_var_single($val, isset($row['name']) ? $row['name'] : '', $tagdata);
                }
                /** ----------------------------------------
                				/**  {url_or_email} - Uses Raw Email Address, Like Channel Module
                				/** ----------------------------------------*/
                if ($key == "url_or_email" and isset($row['url'])) {
                    $tagdata = ee()->TMPL->swap_var_single($val, $row['url'] != '' ? $row['url'] : $row['email'], $tagdata);
                }
                /** ----------------------------------------
                				/**  {url_as_author}
                				/** ----------------------------------------*/
                if ($key == "url_as_author" and isset($row['url'])) {
                    if ($row['url'] != '') {
                        $tagdata = ee()->TMPL->swap_var_single($val, "<a href=\"" . $row['url'] . "\">" . $row['name'] . "</a>", $tagdata);
                    } else {
                        $tagdata = ee()->TMPL->swap_var_single($val, $row['name'], $tagdata);
                    }
                }
                /** ----------------------------------------
                				/**  {url_or_email_as_author}
                				/** ----------------------------------------*/
                if ($key == "url_or_email_as_author" and isset($row['url'])) {
                    if ($row['url'] != '') {
                        $tagdata = ee()->TMPL->swap_var_single($val, "<a href=\"" . $row['url'] . "\">" . $row['name'] . "</a>", $tagdata);
                    } else {
                        if ($row['email'] != '') {
                            $tagdata = ee()->TMPL->swap_var_single($val, ee()->typography->encode_email($row['email'], $row['name']), $tagdata);
                        } else {
                            $tagdata = ee()->TMPL->swap_var_single($val, $row['name'], $tagdata);
                        }
                    }
                }
                /** ----------------------------------------
                				/**  {url_or_email_as_link}
                				/** ----------------------------------------*/
                if ($key == "url_or_email_as_link" and isset($row['url'])) {
                    if ($row['url'] != '') {
                        $tagdata = ee()->TMPL->swap_var_single($val, "<a href=\"" . $row['url'] . "\">" . $row['url'] . "</a>", $tagdata);
                    } else {
                        if ($row['email'] != '') {
                            $tagdata = ee()->TMPL->swap_var_single($val, ee()->typography->encode_email($row['email']), $tagdata);
                        } else {
                            $tagdata = ee()->TMPL->swap_var_single($val, $row['name'], $tagdata);
                        }
                    }
                }
                /** ----------------------------------------
                				/**  {comment_auto_path}
                				/** ----------------------------------------*/
                if ($key == "comment_auto_path") {
                    $path = $row['comment_url'] == '' ? $row['channel_url'] : $row['comment_url'];
                    $tagdata = ee()->TMPL->swap_var_single($key, $path, $tagdata);
                }
                /** ----------------------------------------
                				/**  {comment_url_title_auto_path}
                				/** ----------------------------------------*/
                if ($key == "comment_url_title_auto_path") {
                    $path = $row['comment_url'] == '' ? $row['channel_url'] : $row['comment_url'];
                    $tagdata = ee()->TMPL->swap_var_single($key, $path . '/' . $row['url_title'], $tagdata);
                }
                /** ----------------------------------------
                				/**  {comment_entry_id_auto_path}
                				/** ----------------------------------------*/
                if ($key == "comment_entry_id_auto_path") {
                    $path = $row['comment_url'] == '' ? $row['channel_url'] : $row['comment_url'];
                    $tagdata = ee()->TMPL->swap_var_single($key, $path . '/' . $row['entry_id'], $tagdata);
                }
                /** ----------------------------------------
                				/**  parse comment_stripped field
                				/** ----------------------------------------*/
                if ($key == "comment_stripped" and isset($row['comment'])) {
                    $tagdata = ee()->TMPL->swap_var_single($key, ee()->functions->encode_ee_tags($row['comment'], TRUE), $tagdata);
                }
                /** ----------------------------------------
                				/**  parse comment field
                				/** ----------------------------------------*/
                if ($key == 'comment' and isset($row['comment'])) {
                    // -------------------------------------------
                    // 'comment_entries_comment_format' hook.
                    //  - Play with the tagdata contents of the comment entries
                    //
                    if (ee()->extensions->active_hook('comment_entries_comment_format') === TRUE) {
                        $comment = ee()->extensions->call('comment_entries_comment_format', $row);
                        if (ee()->extensions->end_script === TRUE) {
                            return;
                        }
                    } else {
                        $comment = ee()->typography->parse_type($row['comment'], array('text_format' => $row['comment_text_formatting'], 'html_format' => $row['comment_html_formatting'], 'auto_links' => $row['comment_auto_link_urls'], 'allow_img_url' => $row['comment_allow_img_urls']));
                    }
                    $tagdata = ee()->TMPL->swap_var_single($key, $comment, $tagdata);
                }
                //  {location}
                if ($key == 'location' and (isset($row['location']) or isset($row['c_location']))) {
                    $tagdata = ee()->TMPL->swap_var_single($key, empty($row['location']) ? $row['c_location'] : $row['location'], $tagdata);
                }
                /** ----------------------------------------
                				/**  {signature}
                				/** ----------------------------------------*/
                if ($key == "signature") {
                    if (ee()->session->userdata('display_signatures') == 'n' or !isset($row['signature']) or $row['signature'] == '' or ee()->session->userdata('display_signatures') == 'n') {
                        $tagdata = ee()->TMPL->swap_var_single($key, '', $tagdata);
                    } else {
                        $tagdata = ee()->TMPL->swap_var_single($key, ee()->typography->parse_type($row['signature'], array('text_format' => 'xhtml', 'html_format' => 'safe', 'auto_links' => 'y', 'allow_img_url' => ee()->config->item('sig_allow_img_hotlink'))), $tagdata);
                    }
                }
                if ($key == "signature_image_url") {
                    if (ee()->session->userdata('display_signatures') == 'n' or $row['sig_img_filename'] == '' or ee()->session->userdata('display_signatures') == 'n') {
                        $tagdata = ee()->TMPL->swap_var_single($key, '', $tagdata);
                        $tagdata = ee()->TMPL->swap_var_single('signature_image_width', '', $tagdata);
                        $tagdata = ee()->TMPL->swap_var_single('signature_image_height', '', $tagdata);
                    } else {
                        $tagdata = ee()->TMPL->swap_var_single($key, ee()->config->slash_item('sig_img_url') . $row['sig_img_filename'], $tagdata);
                        $tagdata = ee()->TMPL->swap_var_single('signature_image_width', $row['sig_img_width'], $tagdata);
                        $tagdata = ee()->TMPL->swap_var_single('signature_image_height', $row['sig_img_height'], $tagdata);
                    }
                }
                if ($key == "avatar_url") {
                    if (!isset($row['avatar_filename'])) {
                        $row['avatar_filename'] = '';
                    }
                    if (ee()->session->userdata('display_avatars') == 'n' or $row['avatar_filename'] == '' or ee()->session->userdata('display_avatars') == 'n') {
                        $tagdata = ee()->TMPL->swap_var_single($key, '', $tagdata);
                        $tagdata = ee()->TMPL->swap_var_single('avatar_image_width', '', $tagdata);
                        $tagdata = ee()->TMPL->swap_var_single('avatar_image_height', '', $tagdata);
                    } else {
                        $tagdata = ee()->TMPL->swap_var_single($key, ee()->config->slash_item('avatar_url') . $row['avatar_filename'], $tagdata);
                        $tagdata = ee()->TMPL->swap_var_single('avatar_image_width', $row['avatar_width'], $tagdata);
                        $tagdata = ee()->TMPL->swap_var_single('avatar_image_height', $row['avatar_height'], $tagdata);
                    }
                }
                if ($key == "photo_url") {
                    if (!isset($row['photo_filename'])) {
                        $row['photo_filename'] = '';
                    }
                    if (ee()->session->userdata('display_photos') == 'n' or $row['photo_filename'] == '' or ee()->session->userdata('display_photos') == 'n') {
                        $tagdata = ee()->TMPL->swap_var_single($key, '', $tagdata);
                        $tagdata = ee()->TMPL->swap_var_single('photo_image_width', '', $tagdata);
                        $tagdata = ee()->TMPL->swap_var_single('photo_image_height', '', $tagdata);
                    } else {
                        $tagdata = ee()->TMPL->swap_var_single($key, ee()->config->slash_item('photo_url') . $row['photo_filename'], $tagdata);
                        $tagdata = ee()->TMPL->swap_var_single('photo_image_width', $row['photo_width'], $tagdata);
                        $tagdata = ee()->TMPL->swap_var_single('photo_image_height', $row['photo_height'], $tagdata);
                    }
                }
                /** ----------------------------------------
                				/**  parse basic fields
                				/** ----------------------------------------*/
                if (isset($row[$val]) && $val != 'member_id') {
                    $tagdata = ee()->TMPL->swap_var_single($val, $row[$val], $tagdata);
                }
                /** ----------------------------------------
                				/**  parse custom member fields
                				/** ----------------------------------------*/
                if (isset($mfields[$val])) {
                    // Since comments do not necessarily require registration, and since
                    // you are allowed to put custom member variables in comments,
                    // we delete them if no such row exists
                    $return_val = isset($row['m_field_id_' . $mfields[$val]]) ? $row['m_field_id_' . $mfields[$val]] : '';
                    $tagdata = ee()->TMPL->swap_var_single($val, $return_val, $tagdata);
                }
                /** ----------------------------------------
                				/**  Clean up left over member variables
                				/** ----------------------------------------*/
                if (in_array($val, $member_vars)) {
                    $tagdata = str_replace(LD . $val . RD, '', $tagdata);
                }
            }
            if ($this->show_anchor == TRUE) {
                $return .= "<a name=\"" . $item_count . "\"></a>\n";
            }
            $return .= $tagdata;
            $item_count++;
        }
        /** ----------------------------------------
        		/**  Parse path variable
        		/** ----------------------------------------*/
        $return = preg_replace_callback("/" . LD . "\\s*path=(.+?)" . RD . "/", array(&ee()->functions, 'create_url'), $return);
        /** ----------------------------------------
        		/**  Add pagination to result
        		/** ----------------------------------------*/
        if ($enabled['pagination']) {
            return $pagination->render($return);
        } else {
            return $return;
        }
    }