/** * 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') . '&result_path=' . $result_path . '&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; } }
/** ---------------------------------------- /** 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; }
/** * Get an EntryCollection based on the state of ee()->TMPL * * @param Closure|null $callback receieves a query builder object as the first parameter * @return \rsanchez\Deep\Collection\EntryCollection */ protected function getEntries(Closure $callback = null) { foreach ($this->getEntriesDefaultParameters() as $key => $value) { if (!isset(ee()->TMPL->tagparams[$key])) { ee()->TMPL->tagparams[$key] = $value; } } $disabled = empty(ee()->TMPL->tagparams['disable']) ? array() : explode('|', ee()->TMPL->tagparams['disable']); $this->paginator = ee()->pagination->create(); $limit = ee()->TMPL->fetch_param('limit'); ee()->TMPL->tagdata = $this->paginator->prepare(ee()->TMPL->tagdata); $customFieldsEnabled = !in_array('custom_fields', $disabled); $memberDataEnabled = !in_array('members', $disabled); $paginationEnabled = !in_array('pagination', $disabled); $categoriesEnabled = !in_array('categories', $disabled); $categoryFieldsEnabled = $categoriesEnabled && !in_array('category_fields', $disabled); if ($limit && $paginationEnabled) { unset(ee()->TMPL->tagparams['offset']); } else { $this->paginator->paginate = false; } $uri = ee()->uri->page_query_string ?: ee()->uri->query_string; if (preg_match('#^((.*?)/)?P\\d+/?$#', $uri, $match)) { $uri = $match[2]; } if (!$uri && ee()->TMPL->fetch_param('require_entry') === 'yes') { return ee()->TMPL->no_results(); } ee()->TMPL->tagparams['category_request'] = false; $singleEntry = false; $relatedCategoriesMode = ee()->TMPL->fetch_param('related_categories_mode') === 'yes'; $dynamic = ee()->TMPL->fetch_param('dynamic', 'yes') === 'yes'; $query = $this->app->make($customFieldsEnabled ? 'Entry' : 'Title')->newQuery(); if ($uri && ($dynamic || $relatedCategoriesMode)) { $segments = explode('/', $uri); $lastSegment = array_pop($segments); $penultimateSegment = array_pop($segments); if (preg_match('#(^|/)(\\d{4})/(\\d{2})(/(\\d{2}))?/?$#', $uri, $match)) { ee()->TMPL->tagparams['year'] = $match[2]; ee()->TMPL->tagparams['month'] = $match[3]; if (isset($match[5])) { ee()->TMPL->tagparams['day'] = $match[5]; } } elseif (is_numeric($lastSegment)) { if ($relatedCategoriesMode) { $singleEntry = true; $query->relatedCategories($lastSegment); ee()->TMPL->tagparams['dynamic'] = 'no'; } else { ee()->TMPL->tagparams['entry_id'] = $lastSegment; } } elseif (ee()->config->item('use_category_name') === 'y' && $penultimateSegment === ee()->config->item('reserved_category_word')) { ee()->TMPL->tagparams['category_name'] = $lastSegment; ee()->TMPL->tagparams['category_request'] = true; } elseif (ee()->config->item('use_category_name') !== 'y' && preg_match('#(^|/)C(\\d+)#', $uri, $match)) { ee()->TMPL->tagparams['category'] = $match[2]; ee()->TMPL->tagparams['category_request'] = true; } else { if ($relatedCategoriesMode) { $singleEntry = true; $query->relatedCategoriesUrlTitle($lastSegment); ee()->TMPL->tagparams['dynamic'] = 'no'; } else { ee()->TMPL->tagparams['url_title'] = $lastSegment; } } } if ($relatedCategoriesMode && !$singleEntry) { return ee()->TMPL->no_results(); } $query->tagparams(ee()->TMPL->tagparams); if ($categoriesEnabled) { $query->withCategories(function ($query) use($categoryFieldsEnabled) { if ($categoryFieldsEnabled) { $query->withFields(); } return $query->orderBy('categories.group_id')->orderBy('categories.parent_id')->orderBy('categories.cat_order'); }); } if ($memberDataEnabled) { $query->withAuthorFields(); } $connection = $query->getQuery()->getConnection(); $tablePrefix = $connection->getTablePrefix(); if (strpos(ee()->TMPL->tagdata, 'comment_subscriber_total') !== false) { $subquery = "(select count(*) " . "from `{$tablePrefix}comment_subscriptions` " . "where `{$tablePrefix}comment_subscriptions`.`entry_id` " . "= `{$tablePrefix}`channel_titles`.`entry_id`) " . "as `comment_subscriber_total`"; $query->addSelect($connection->raw($subquery)); } $prefix = ee()->TMPL->fetch_param('var_prefix') ? ee()->TMPL->fetch_param('var_prefix') . ':' : ''; if (strpos(ee()->TMPL->tagdata, '{' . $prefix . 'parents') !== false) { $query->withParents(); } if (strpos(ee()->TMPL->tagdata, '{' . $prefix . 'siblings') !== false) { $query->withSiblings(); } if (is_callable($callback)) { $callback($query); } ee()->TMPL->tagparams['absolute_results'] = $limit; if ($this->paginator->paginate) { ee()->TMPL->tagparams['absolute_results'] = $query->getQuery()->getPaginationCount(); $this->paginator->build(ee()->TMPL->tagparams['absolute_results'], $limit); if ($this->paginator->offset) { $query->skip($this->paginator->offset); ee()->TMPL->tagparams['offset'] = $this->paginator->offset; } } return $query->get(); }