/** * Call major cache updating functions for list of Post objects. * * @package WordPress * @subpackage Cache * @since 1.5.0 * * @uses $wpdb * @uses update_post_cache() * @uses update_object_term_cache() * @uses update_postmeta_cache() * * @param array $posts Array of Post objects * @param string $post_type The post type of the posts in $posts. Default is 'post'. * @param bool $update_term_cache Whether to update the term cache. Default is true. * @param bool $update_meta_cache Whether to update the meta cache. Default is true. */ function update_post_caches(&$posts, $post_type = 'post', $update_term_cache = true, $update_meta_cache = true) { // No point in doing all this work if we didn't match any posts. if (!$posts) { return; } update_post_cache($posts); $post_ids = array(); foreach ($posts as $post) { $post_ids[] = $post->ID; } if (empty($post_type)) { $post_type = 'post'; } if ($update_term_cache) { if (is_array($post_type)) { $ptypes = $post_type; } elseif ('any' == $post_type) { // Just use the post_types in the supplied posts. foreach ($posts as $post) { $ptypes[] = $post->post_type; } $ptypes = array_unique($ptypes); } else { $ptypes = array($post_type); } if (!empty($ptypes)) { update_object_term_cache($post_ids, $ptypes); } } if ($update_meta_cache) { update_postmeta_cache($post_ids); } }
/** * Alias of update_post_cache(). * * @see update_post_cache() Posts and pages are the same, alias is intentional * * @since 1.5.1 * @deprecated 3.4.0 * * @param array $pages list of page objects */ function update_page_cache(&$pages) { _deprecated_function(__FUNCTION__, '3.4', 'update_post_cache()'); update_post_cache($pages); }
/** * Builds the sitemap and writes it into a xml file. * * @return array An array with messages such as failed writes etc. */ function BuildSitemap() { global $wpdb, $posts, $wp_version; //Other plugins can detect if the building process is active $this->_isActive = true; if (true) { $fileName = $this->GetXmlPath(); if ($this->IsFileWritable($fileName)) { $this->_fileHandle = fopen($fileName, "w"); } } //Write gzipped sitemap file if ($this->IsGzipEnabled()) { $fileName = $this->GetZipPath(); if ($this->IsFileWritable($fileName)) { $this->_fileZipHandle = gzopen($fileName, "w1"); } } if (!$this->_fileHandle && !$this->_fileZipHandle) { return; } //Content of the XML file $this->AddElement(new TF_SEO_SitemapGeneratorXmlEntry('<?xml version="1.0" encoding="UTF-8"' . '?' . '>')); //All comments as an asso. Array (postID=>commentCount) $comments = array(); //Full number of comments $commentCount = 0; //Go XML! $this->AddElement(new TF_SEO_SitemapGeneratorXmlEntry('<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">')); $home = home_url(); $homePid = 0; //Add the home page (WITH a slash!) if (true) { if ('page' == get_option('show_on_front') && get_option('page_on_front')) { $pageOnFront = get_option('page_on_front'); $p = get_page($pageOnFront); if ($p) { $homePid = $p->ID; $this->AddUrl(trailingslashit($home), $this->GetTimestampFromMySql($p->post_modified_gmt && $p->post_modified_gmt != '0000-00-00 00:00:00' ? $p->post_modified_gmt : $p->post_date_gmt), $this->GetOption("cf_home"), $this->GetOption("pr_home")); } } else { $this->AddUrl(trailingslashit($home), $this->GetTimestampFromMySql(get_lastpostmodified('GMT')), $this->GetOption("cf_home"), $this->GetOption("pr_home")); } } //Add the posts if (true) { $wpCompat = false; $excludes = ''; //Excluded posts and pages (user enetered ID) $exclCats = ''; // Excluded cats $sql = "SELECT `ID`, `post_author`, `post_date`, `post_date_gmt`, `post_status`, `post_name`, `post_modified`, `post_modified_gmt`, `post_parent`, `post_type` FROM `" . $wpdb->posts . "` WHERE "; $where = '('; if (true) { $where .= " (post_status = 'publish' AND (post_type in (''"; foreach (get_post_types() as $customType) { if (!in_array($customType, array('revision', 'nav_menu_item', 'attachment'))) { if (!tfuse_options('seo_xmls_exclude_posttype_' . $customType, false) && 'STOP!' != tfuse_options('seo_xmls_exclude_posttype_' . $customType, 'STOP!')) { $where .= ",'{$customType}'"; } } } $where .= "))) "; } $where .= ") "; $where .= " AND post_password='' ORDER BY post_modified DESC"; $sql .= $where; if ($this->GetOption("b_max_posts") > 0) { $sql .= " LIMIT 0," . $this->GetOption("b_max_posts"); } $postCount = intval($wpdb->get_var("SELECT COUNT(*) AS cnt FROM `" . $wpdb->posts . "` WHERE " . $where, 0, 0)); //Create a new connection because we are using mysql_unbuffered_query and don't want to disturb the WP connection //Safe Mode for other plugins which use mysql_query() without a connection handler and will destroy our resultset :( $con = $postRes = null; if (true) { $postRes = mysql_query($sql, $wpdb->dbh); if (!$postRes) { trigger_error("MySQL query failed: " . mysql_error(), E_USER_NOTICE); //E_USER_NOTICE will be displayed on our debug mode return; } } if ($postRes) { $prioProvider = NULL; $z = 1; $zz = 1; //Default priorities $default_prio_posts = $this->GetOption('pr_posts'); $default_prio_pages = $this->GetOption('pr_pages'); //Change frequencies $cf_pages = $this->GetOption('cf_pages'); $cf_posts = $this->GetOption('cf_posts'); $minPrio = $this->GetOption('pr_posts_min'); //Cycle through all posts and add them while ($post = mysql_fetch_object($postRes)) { //Fill the cache with our DB result. Since it's incomplete (no text-content for example), we will clean it later. $cache = array(&$post); update_post_cache($cache); //Set the current working post for other plugins which depend on "the loop" $GLOBALS['post'] =& $post; $permalink = get_permalink($post->ID); if ($permalink != $home && $post->ID != $homePid) { $isPage = false; if ($wpCompat) { $isPage = $post->post_status == 'static'; } else { $isPage = $post->post_type == 'page'; } //Default Priority if auto calc is disabled $prio = 0; if ($isPage) { //Priority for static pages $prio = $default_prio_pages; } else { //Priority for normal posts $prio = $default_prio_posts; } if (!$isPage && $minPrio > 0 && $prio < $minPrio) { $prio = $minPrio; } //Add it $this->AddUrl($permalink, $this->GetTimestampFromMySql($post->post_modified_gmt && $post->post_modified_gmt != '0000-00-00 00:00:00' ? $post->post_modified_gmt : $post->post_date_gmt), $isPage ? $cf_pages : $cf_posts, $prio); if (false) { $subPage = ''; for ($p = 1; $p <= $post->postPages; $p++) { if (get_option('permalink_structure') == '') { $subPage = $permalink . '&paged=' . ($p + 1); } else { $subPage = trailingslashit($permalink) . user_trailingslashit($p + 1, 'single_paged'); } $this->AddUrl($subPage, $this->GetTimestampFromMySql($post->post_modified_gmt && $post->post_modified_gmt != '0000-00-00 00:00:00' ? $post->post_modified_gmt : $post->post_date_gmt), $isPage ? $cf_pages : $cf_posts, $prio); } } } //Update the status every 100 posts and at the end. //If the script breaks because of memory or time limit, //we have a "last reponded" value which can be compared to the server settings if ($zz == 100 || $z == $postCount) { $zz = 0; } else { $zz++; } $z++; //Clean cache because it's incomplete if (version_compare($wp_version, "2.5", ">=")) { //WP 2.5 makes a mysql query for every clean_post_cache to clear the child cache //so I've copied the function here until a patch arrives... wp_cache_delete($post->ID, 'posts'); wp_cache_delete($post->ID, 'post_meta'); clean_object_term_cache($post->ID, 'post'); } else { clean_post_cache($post->ID); } } unset($postRes); unset($prioProvider); } } //Add custom taxonomy pages if (true) { $taxList = array(); foreach (get_taxonomies() as $taxName) { if (!in_array($taxName, array('nav_menu', 'link_category', 'post_format'))) { $taxonomy = get_taxonomy($taxName); if (isset($taxonomy->labels->name) && trim($taxonomy->labels->name) != '') { if (!tfuse_options('seo_xmls_exclude_taxonomy_' . $taxName, false) && 'STOP!' != tfuse_options('seo_xmls_exclude_taxonomy_' . $taxName, 'STOP!')) { if ($taxonomy) { $taxList[] = $wpdb->escape($taxonomy->name); } } } } } if (count($taxList) > 0) { //We're selecting all term information (t.*) plus some additional fields //like the last mod date and the taxonomy name, so WP doesnt need to make //additional queries to build the permalink structure. //This does NOT work for categories and tags yet, because WP uses get_category_link //and get_tag_link internally and that would cause one additional query per term! $sql = "\r\r\n\t\t\t\t\tSELECT\r\r\n\t\t\t\t\t\tt.*,\r\r\n\t\t\t\t\t\ttt.taxonomy AS _taxonomy,\r\r\n\t\t\t\t\t\tUNIX_TIMESTAMP(MAX(post_date_gmt)) as _mod_date\r\r\n\t\t\t\t\tFROM\r\r\n\t\t\t\t\t\t{$wpdb->posts} p ,\r\r\n\t\t\t\t\t\t{$wpdb->term_relationships} r,\r\r\n\t\t\t\t\t\t{$wpdb->terms} t,\r\r\n\t\t\t\t\t\t{$wpdb->term_taxonomy} tt\r\r\n\t\t\t\t\tWHERE\r\r\n\t\t\t\t\t\tp.ID = r.object_id\r\r\n\t\t\t\t\t\tAND p.post_status = 'publish'\r\r\n\t\t\t\t\t\tAND p.post_password = ''\r\r\n\t\t\t\t\t\tAND r.term_taxonomy_id = t.term_id\r\r\n\t\t\t\t\t\tAND t.term_id = tt.term_id\r\r\n\t\t\t\t\t\tAND tt.count > 0\r\r\n\t\t\t\t\t\tAND tt.taxonomy IN ('" . implode("','", $taxList) . "')\r\r\n\t\t\t\t\tGROUP BY \r\r\n\t\t\t\t\t\tt.term_id"; $termInfo = $wpdb->get_results($sql); foreach ($termInfo as $term) { if (!in_array($term->_taxonomy, array('nav_menu', 'link_category', 'post_format'))) { $this->AddUrl(get_term_link($term->slug, $term->_taxonomy), $term->_mod_date, $this->GetOption("cf_tags"), $this->GetOption("pr_tags")); } } } } //Add the custom pages if ($this->_pages && is_array($this->_pages) && count($this->_pages) > 0) { //#type $page TF_SEO_SitemapGeneratorPage foreach ($this->_pages as $page) { $this->AddUrl($page->GetUrl(), $page->getLastMod(), $page->getChangeFreq(), $page->getPriority()); } } do_action('tf_seo_buildmap'); $this->AddElement(new TF_SEO_SitemapGeneratorXmlEntry("</urlset>")); $pingUrl = ''; if (true) { if ($this->_fileHandle && fclose($this->_fileHandle)) { $this->_fileHandle = null; $pingUrl = $this->GetXmlUrl(); } } if ($this->IsGzipEnabled()) { if ($this->_fileZipHandle && fclose($this->_fileZipHandle)) { $this->_fileZipHandle = null; $pingUrl = $this->GetZipUrl(); } } //Ping Google if (!empty($pingUrl)) { $sPingUrl = "http://www.google.com/webmasters/sitemaps/ping?sitemap=" . urlencode($pingUrl); $pingres = $this->RemoteOpen($sPingUrl); if ($pingres == NULL || $pingres === false) { trigger_error("Failed to ping Google: " . htmlspecialchars(strip_tags($pingres)), E_USER_NOTICE); } } //Ping Ask.com if (!empty($pingUrl)) { $sPingUrl = "http://submissions.ask.com/ping?sitemap=" . urlencode($pingUrl); $pingres = $this->RemoteOpen($sPingUrl); if ($pingres == NULL || $pingres === false || strpos($pingres, "successfully received and added") === false) { //Ask.com returns 200 OK even if there was an error, so we need to check the content. trigger_error("Failed to ping Ask.com: " . htmlspecialchars(strip_tags($pingres)), E_USER_NOTICE); } } //Ping Bing if (!empty($pingUrl)) { $sPingUrl = "http://www.bing.com/webmaster/ping.aspx?siteMap=" . urlencode($pingUrl); $pingres = $this->RemoteOpen($sPingUrl); //Bing returns ip/country-based success messages, so there is no way to check the content. Rely on HTTP 500 only then... if ($pingres == NULL || $pingres === false || strpos($pingres, " ") === false) { trigger_error("Failed to ping Bing: " . htmlspecialchars(strip_tags($pingres)), E_USER_NOTICE); } } $this->_isActive = false; //done... return; }
/** * Adds posts and pages to the sitemap. * * @since 1.3 */ protected function posts() { global $wpdb; $post_type = $this->get_info('content_type'); $post_type_is_page = $post_type == 'page'; $post_type_is_post = $post_type == 'post'; if (!($post_type_is_post || $post_type_is_page)) { return false; } $post_ids = $post_attachments = array(); $post_not_in = ''; $limit = $this->getLimit(); $exclude = $this->db->getOption($this->sitemap_type, array(), 'exclude'); if ($exclude && ($ids = wp_parse_id_list($exclude))) { $post_not_in = 'ID NOT IN (' . implode(',', $ids) . ') AND'; } if ($post_type_is_page) { $this->pageForPosts = (int) get_option('page_for_posts'); } // We retrieve a few more fields than needed to make get_permalink() work properly $posts = $wpdb->get_results("SELECT ID, post_date, post_status, post_name, post_modified, post_parent, post_type\n\t\t\t FROM {$wpdb->posts}\n\t\t\t WHERE {$post_not_in} post_type = '{$post_type}' AND post_status = 'publish' AND post_password = ''\n\t\t\t ORDER BY post_modified DESC\n\t\t\t LIMIT {$limit}"); if (!$posts) { return false; } foreach ($posts as $index => $post) { $post = sanitize_post($post, 'raw'); $post_ids[] = $post->ID; } if ($post_type_is_post && $this->blog) { $this->blog->post_modified = $posts[0]->post_modified; } if ($this->db->getOption('images', true)) { $ids = implode(',', $post_ids); $attachments = $wpdb->get_results("SELECT ID, post_title, post_content, post_excerpt, post_parent, post_type\n\t\t\t\t FROM {$wpdb->posts}\n\t\t\t\t WHERE post_parent IN ({$ids}) AND post_type = 'attachment' AND post_mime_type LIKE 'image/%'\n\t\t\t\t ORDER BY post_modified DESC"); if ($attachments) { $this->isImageSitemap = true; foreach ($attachments as $attachment) { $attachment = sanitize_post($attachment, 'raw'); $post_ids[] = $attachment->ID; $post_attachments[$attachment->post_parent][] = $attachment; } update_post_cache($attachments); } } // Retrieves and stores into the cache the metadata we need later update_meta_cache('post', $post_ids); // This hack lets us save a lot of queries that would be performed when we call get_permalink() update_post_cache($posts); $changefreq = $this->get_info('changefreq'); $priority = $this->get_info('priority'); foreach ($posts as $post) { $images = null; if (isset($post_attachments[$post->ID])) { $images =& $post_attachments[$post->ID]; } if ($post->ID == $this->pageOnFront) { $this->home = $post; $this->home->images = $images; continue; } elseif ($post->ID == $this->pageForPosts) { $this->blog = $post; $this->blog->changefreq = $changefreq; $this->blog->priority = $priority; $this->blog->images = $images; continue; } $this->addUrlItem(get_permalink($post), $post->post_modified, $this->db->getPostMeta($post->ID, 'changefreq', $changefreq), $this->db->getPostMeta($post->ID, 'priority', $priority), $images); } }
/** * Call major cache updating functions for list of Post objects. * * @package WordPress * @subpackage Cache * @since 1.5.0 * * @uses $wpdb * @uses update_post_cache() * @uses update_object_term_cache() * @uses update_postmeta_cache() * * @param array $posts Array of Post objects * @param string $post_type The post type of the posts in $posts. Default is 'post'. * @param bool $update_term_cache Whether to update the term cache. Default is true. * @param bool $update_meta_cache Whether to update the meta cache. Default is true. */ function update_post_caches(&$posts, $post_type = 'post', $update_term_cache = true, $update_meta_cache = true) { // No point in doing all this work if we didn't match any posts. if (!$posts) { return; } update_post_cache($posts); $post_ids = array(); foreach ($posts as $post) { $post_ids[] = $post->ID; } if (empty($post_type)) { $post_type = 'post'; } if (!is_array($post_type) && 'any' != $post_type && $update_term_cache) { update_object_term_cache($post_ids, $post_type); } if ($update_meta_cache) { update_postmeta_cache($post_ids); } }
/** * update_post_caches() - Call major cache updating functions for list of Post objects. * * @package WordPress * @subpackage Cache * @since 1.5 * * @uses $wpdb * @uses update_post_cache() * @uses update_object_term_cache() * @uses update_postmeta_cache() * * @param array $posts Array of Post objects */ function update_post_caches(&$posts) { // No point in doing all this work if we didn't match any posts. if (!$posts) { return; } update_post_cache($posts); $post_ids = array(); for ($i = 0; $i < count($posts); $i++) { $post_ids[] = $posts[$i]->ID; } update_object_term_cache($post_ids, 'post'); update_postmeta_cache($post_ids); }
/** * Load all posts with one query, to prime the cache * * @see get_post() * @since 1.0.0 * * @param array $all_post_ids List of Post IDs * @param bool $update_meta_cache Whether to update the Post Meta Cache (for table options and visibility) */ public function load_posts(array $all_post_ids, $update_meta_cache = true) { global $wpdb; // Split post loading, to save memory $offset = 0; $length = 100; // 100 posts at a time $number_of_posts = count($all_post_ids); while ($offset < $number_of_posts) { $post_ids = array_slice($all_post_ids, $offset, $length); $post_ids = _get_non_cached_ids($post_ids, 'posts'); // Don't load posts that are in the cache already if (!empty($post_ids)) { $post_ids_list = implode(',', $post_ids); $posts = $wpdb->get_results("SELECT {$wpdb->posts}.* FROM {$wpdb->posts} WHERE ID IN ({$post_ids_list})"); update_post_cache($posts); if ($update_meta_cache) { update_meta_cache('post', $post_ids); // get all post meta data for all table posts, @see get_post_meta() } } $offset += $length; // next array_slice() $offset } }
public static function get_recent_pages($orders, $pagination, $allow_autodrafts = false) { global $wpdb; if (!array_key_exists('date', $orders)) { $orders['date'] = 'DESC'; } $sql_autodrafts = " AND post_status != 'auto-draft' "; if ($allow_autodrafts) { $sql_autodrafts = ''; } $total_items = $wpdb->get_var("SELECT count(*) FROM {$wpdb->posts} WHERE post_type = 'page' {$sql_autodrafts}"); $current_page = !empty($pagination['current_page']) ? $pagination['current_page'] : 1; $nb_per_page = !empty($pagination['nb_per_page']) ? $pagination['nb_per_page'] : 10; $total_pages = $nb_per_page > 0 ? ceil($total_items / $nb_per_page) : 0; if ($current_page > $total_pages) { $current_page = $total_pages; } $offset = $nb_per_page * ($current_page - 1); $orderby_data = self::get_sql_orderby_data($orders); $join = $orderby_data['join']; $order_by = $orderby_data['order_by']; //Retrieve Recent page, then cache retrieved data: //Cannot use get_pages() here because we want to filter/order by Templates, //marked page infos etc... but we're forgiven if we cache the data after, no? $sql = "SELECT * FROM {$wpdb->posts} AS p \r\n\t\t\t\t\t\t {$join}\r\n\t\t\t\t\t\t WHERE post_type = 'page' \r\n\t\t\t\t\t\t {$sql_autodrafts}\r\n\t\t\t\t\t\t {$order_by} \r\n\t\t\t\t\t\t LIMIT {$offset}, {$nb_per_page}\r\n\t\t\t\t\t\t "; $pages = $wpdb->get_results($sql); //Inspired from WP get_pages() : //Sanitize before caching so it'll only get done once $num_pages = count($pages); for ($i = 0; $i < $num_pages; $i++) { $pages[$i] = sanitize_post($pages[$i], 'raw'); } // Update cache. update_post_cache($pages); return array('pages' => $pages, 'pagination' => compact('current_page', 'nb_per_page', 'total_items', 'total_pages')); }
/** * Builds the sitemap and writes it into a xml file. * * ATTENTION PLUGIN DEVELOPERS! DONT CALL THIS METHOD DIRECTLY! * The method is probably not available, since it is only loaded when needed. * Use do_action("sm_rebuild"); if you want to rebuild the sitemap. * Please refer to the documentation.txt for more details. * * @since 3.0 * @access public * @author Arne Brachhold <himself [at] arnebrachhold [dot] de> * @return array An array with messages such as failed writes etc. */ function BuildSitemap() { global $nxtdb, $posts, $nxt_version; $this->Initate(); if ($this->GetOption("b_memory") != '') { @ini_set("memory_limit", $this->GetOption("b_memory")); } if ($this->GetOption("b_time") != -1) { @set_time_limit($this->GetOption("b_time")); } //This object saves the status information of the script directly to the database $status = new GoogleSitemapGeneratorStatus(); //Other plugins can detect if the building process is active $this->_isActive = true; //$this->AddElement(new GoogleSitemapGeneratorXmlEntry()); //Debug mode? $debug = $this->GetOption("b_debug"); if ($this->GetOption("b_xml")) { $fileName = $this->GetXmlPath(); $status->StartXml($this->GetXmlPath(), $this->GetXmlUrl()); if ($this->IsFileWritable($fileName)) { $this->_fileHandle = fopen($fileName, "w"); if (!$this->_fileHandle) { $status->EndXml(false, "Not openable"); } } else { $status->EndXml(false, "not writable"); } } //Write gzipped sitemap file if ($this->IsGzipEnabled()) { $fileName = $this->GetZipPath(); $status->StartZip($this->GetZipPath(), $this->GetZipUrl()); if ($this->IsFileWritable($fileName)) { $this->_fileZipHandle = gzopen($fileName, "w1"); if (!$this->_fileZipHandle) { $status->EndZip(false, "Not openable"); } } else { $status->EndZip(false, "not writable"); } } if (!$this->_fileHandle && !$this->_fileZipHandle) { $status->End(); return; } //Content of the XML file $this->AddElement(new GoogleSitemapGeneratorXmlEntry('<?xml version="1.0" encoding="UTF-8"' . '?' . '>')); $styleSheet = $this->GetDefaultStyle() && $this->GetOption('b_style_default') === true ? $this->GetDefaultStyle() : $this->GetOption('b_style'); if (!empty($styleSheet)) { $this->AddElement(new GoogleSitemapGeneratorXmlEntry('<' . '?xml-stylesheet type="text/xsl" href="' . $styleSheet . '"?' . '>')); } $this->AddElement(new GoogleSitemapGeneratorDebugEntry("generator=\"nxtclass/" . get_bloginfo('version') . "\"")); $this->AddElement(new GoogleSitemapGeneratorDebugEntry("sitemap-generator-url=\"http://www.arnebrachhold.de\" sitemap-generator-version=\"" . $this->GetVersion() . "\"")); $this->AddElement(new GoogleSitemapGeneratorDebugEntry("generated-on=\"" . date(get_option("date_format") . " " . get_option("time_format")) . "\"")); //All comments as an asso. Array (postID=>commentCount) $comments = $this->GetOption("b_prio_provider") != "" ? $this->GetComments() : array(); //Full number of comments $commentCount = count($comments) > 0 ? $this->GetCommentCount($comments) : 0; if ($debug && $this->GetOption("b_prio_provider") != "") { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Total comment count: " . $commentCount)); } //Go XML! $this->AddElement(new GoogleSitemapGeneratorXmlEntry('<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">')); $home = get_bloginfo('url'); $homePid = 0; // Load qTranslate settings require_once "sitemap-qtranslate.php"; $qt = qt_settings(); //Add the home page (WITH a slash!) if ($this->GetOption("in_home")) { if ('page' == get_option('show_on_front') && get_option('page_on_front')) { $pageOnFront = get_option('page_on_front'); $p = get_page($pageOnFront); if ($p) { $homePid = $p->ID; if (!$qt["enabled"]) { $this->AddUrl(trailingslashit($home), $this->GetTimestampFromMySql($p->post_modified_gmt && $p->post_modified_gmt != '0000-00-00 00:00:00' ? $p->post_modified_gmt : $p->post_date_gmt), $this->GetOption("cf_home"), $this->GetOption("pr_home")); } qt_permalink($qt, trailingslashit($home), null, $p->post_modified_gmt && $p->post_modified_gmt != '0000-00-00 00:00:00' ? $p->post_modified_gmt : $p->post_date_gmt, $this->GetOption("cf_home"), $this->GetOption("pr_home"), $this); } } else { if (!$qt["enabled"]) { $this->AddUrl(trailingslashit($home), $this->GetTimestampFromMySql(get_lastpostmodified('GMT')), $this->GetOption("cf_home"), $this->GetOption("pr_home")); } qt_permalink($qt, trailingslashit($home), null, get_lastpostmodified('GMT'), $this->GetOption("cf_home"), $this->GetOption("pr_home"), $this); } } //Add the posts if ($this->GetOption("in_posts") || $this->GetOption("in_pages")) { if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Start Postings")); } //Pre 2.1 compatibility. 2.1 introduced 'future' as post_status so we don't need to check post_date $nxtCompat = floatval($nxt_version) < 2.1; $excludes = $this->GetOption('b_exclude'); //Excluded posts and pages (user enetered ID) $exclCats = $this->GetOption("b_exclude_cats"); // Excluded cats if ($exclCats && count($exclCats) > 0 && $this->IsTaxonomySupported()) { $excludedCatPosts = get_objects_in_term($exclCats, "category"); // Get all posts in excl. cats. Unforttunately this also gives us pages, revisions and so on... //Remove the pages, revisions etc from the exclude by category list, because they are always in the uncategorized one. if (count($excludedCatPosts) > 0) { $exclPages = $nxtdb->get_col("SELECT ID FROM `" . $nxtdb->posts . "` WHERE post_type!='post' AND ID IN ('" . implode("','", $excludedCatPosts) . "')"); $exclPages = array_map('intval', $exclPages); //Remove the pages from the exlusion list before if (count($exclPages) > 0) { $excludedCatPosts = array_diff($excludedCatPosts, $exclPages); } //Merge the category exclusion list with the users one if (count($excludedCatPosts) > 0) { $excludes = array_merge($excludes, $excludedCatPosts); } } } $contentStmt = ''; if ($qt["enabled"]) { $contentStmt .= ', post_content '; } $postPageStmt = ''; $inSubPages = $this->GetOption('in_posts_sub') === true; if ($inSubPages && $this->GetOption('in_posts') === true) { $pageDivider = '<!--nextpage-->'; $postPageStmt = ", (character_length(`post_content`) - character_length(REPLACE(`post_content`, '{$pageDivider}', ''))) / " . strlen($pageDivider) . " as postPages"; } $sql = "SELECT `ID`, `post_author`, `post_date`, `post_date_gmt`, `post_status`, `post_name`, `post_modified`, `post_modified_gmt`, `post_parent`, `post_type` {$postPageStmt} {$contentStmt} FROM `" . $nxtdb->posts . "` WHERE "; $where = '('; if ($this->GetOption('in_posts')) { //nxt < 2.1: posts are post_status = publish //nxt >= 2.1: post_type must be 'post', no date check required because future posts are post_status='future' if ($nxtCompat) { $where .= "(post_status = 'publish' AND post_date_gmt <= '" . gmdate('Y-m-d H:i:59') . "')"; } else { if ($this->IsCustomPostTypesSupported() && count($this->GetOption('in_customtypes')) > 0) { $where .= " (post_status = 'publish' AND (post_type in ('','post'"; foreach ($this->GetOption('in_customtypes') as $customType) { $where .= ",'{$customType}'"; } $where .= "))) "; } else { $where .= " (post_status = 'publish' AND (post_type = 'post' OR post_type = '')) "; } } } if ($this->GetOption('in_pages')) { if ($this->GetOption('in_posts')) { $where .= " OR "; } if ($nxtCompat) { //nxt < 2.1: posts have post_status = published, pages have post_status = static $where .= " post_status='static' "; } else { //nxt >= 2.1: posts have post_type = 'post' and pages have post_type = 'page'. Both must be published. $where .= " (post_status = 'publish' AND post_type = 'page') "; } } $where .= ") "; if (is_array($excludes) && count($excludes) > 0) { $where .= " AND ID NOT IN ('" . implode("','", $excludes) . "')"; } $where .= " AND post_password='' ORDER BY post_modified DESC"; $sql .= $where; if ($this->GetOption("b_max_posts") > 0) { $sql .= " LIMIT 0," . $this->GetOption("b_max_posts"); } $postCount = intval($nxtdb->get_var("SELECT COUNT(*) AS cnt FROM `" . $nxtdb->posts . "` WHERE " . $where, 0, 0)); //Create a new connection because we are using mysql_unbuffered_query and don't want to disturb the nxt connection //Safe Mode for other plugins which use mysql_query() without a connection handler and will destroy our resultset :( $con = $postRes = null; //In 2.2, a bug which prevented additional DB connections was fixed if (floatval($nxt_version) < 2.2) { $this->SetOption("b_safemode", true); } if ($this->GetOption("b_safemode") === true) { $postRes = mysql_query($sql, $nxtdb->dbh); if (!$postRes) { trigger_error("MySQL query failed: " . mysql_error(), E_USER_NOTICE); //E_USER_NOTICE will be displayed on our debug mode return; } } else { $con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD, true); if (!$con) { trigger_error("MySQL Connection failed: " . mysql_error(), E_USER_NOTICE); return; } if (!mysql_select_db(DB_NAME, $con)) { trigger_error("MySQL DB Select failed: " . mysql_error(), E_USER_NOTICE); return; } $postRes = mysql_unbuffered_query($sql, $con); if (!$postRes) { trigger_error("MySQL unbuffered query failed: " . mysql_error(), E_USER_NOTICE); return; } } if ($postRes) { //#type $prioProvider GoogleSitemapGeneratorPrioProviderBase $prioProvider = NULL; if ($this->GetOption("b_prio_provider") != '') { $providerClass = $this->GetOption('b_prio_provider'); $prioProvider = new $providerClass($commentCount, $postCount); } //$posts is used by Alex King's Popularity Contest plugin //if($posts == null || !is_array($posts)) { // $posts = &$postRes; //} $z = 1; $zz = 1; //Default priorities $default_prio_posts = $this->GetOption('pr_posts'); $default_prio_pages = $this->GetOption('pr_pages'); //Change frequencies $cf_pages = $this->GetOption('cf_pages'); $cf_posts = $this->GetOption('cf_posts'); $minPrio = $this->GetOption('pr_posts_min'); //Cycle through all posts and add them while ($post = mysql_fetch_object($postRes)) { //Fill the cache with our DB result. Since it's incomplete (no text-content for example), we will clean it later. $cache = array(&$post); update_post_cache($cache); //Set the current working post for other plugins which depend on "the loop" $GLOBALS['post'] =& $post; $permalink = get_permalink($post->ID); if ($permalink != $home && $post->ID != $homePid) { $isPage = false; if ($nxtCompat) { $isPage = $post->post_status == 'static'; } else { $isPage = $post->post_type == 'page'; } //Default Priority if auto calc is disabled $prio = 0; if ($isPage) { //Priority for static pages $prio = $default_prio_pages; } else { //Priority for normal posts $prio = $default_prio_posts; } //If priority calc. is enabled, calculate (but only for posts, not pages)! if ($prioProvider !== null && !$isPage) { //Comment count for this post $cmtcnt = isset($comments[$post->ID]) ? $comments[$post->ID] : 0; $prio = $prioProvider->GetPostPriority($post->ID, $cmtcnt, $post); if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry('Debug: Priority report of postID ' . $post->ID . ': Comments: ' . $cmtcnt . ' of ' . $commentCount . ' = ' . $prio . ' points')); } } if (!$isPage && $minPrio > 0 && $prio < $minPrio) { $prio = $minPrio; } //Add it if (!$qt["enabled"]) { $this->AddUrl($permalink, $this->GetTimestampFromMySql($post->post_modified_gmt && $post->post_modified_gmt != '0000-00-00 00:00:00' ? $post->post_modified_gmt : $post->post_date_gmt), $isPage ? $cf_pages : $cf_posts, $prio); } qt_permalink($qt, $permalink, $post->post_content, $post->post_modified_gmt && $post->post_modified_gmt != '0000-00-00 00:00:00' ? $post->post_modified_gmt : $post->post_date_gmt, $isPage ? $cf_pages : $cf_posts, $prio, $this); if ($inSubPages) { $subPage = ''; for ($p = 1; $p <= $post->postPages; $p++) { if (get_option('permalink_structure') == '') { $subPage = $permalink . '&page=' . ($p + 1); } else { $subPage = trailingslashit($permalink) . user_trailingslashit($p + 1, 'single_paged'); } if (!$qt["enabled"]) { $this->AddUrl($subPage, $this->GetTimestampFromMySql($post->post_modified_gmt && $post->post_modified_gmt != '0000-00-00 00:00:00' ? $post->post_modified_gmt : $post->post_date_gmt), $isPage ? $cf_pages : $cf_posts, $prio); } //qt_permalink($qt, $subPage, $post->post_content, ($post->post_modified_gmt && $post->post_modified_gmt!='0000-00-00 00:00:00'?$post->post_modified_gmt:$post->post_date_gmt), ($isPage?$cf_pages:$cf_posts), $prio, $this); } } } //Update the status every 100 posts and at the end. //If the script breaks because of memory or time limit, //we have a "last reponded" value which can be compared to the server settings if ($zz == 100 || $z == $postCount) { $status->SaveStep($z); $zz = 0; } else { $zz++; } $z++; //Clean cache because it's incomplete if (version_compare($nxt_version, "2.5", ">=")) { //nxt 2.5 makes a mysql query for every clean_post_cache to clear the child cache //so I've copied the function here until a patch arrives... nxt_cache_delete($post->ID, 'posts'); nxt_cache_delete($post->ID, 'post_meta'); clean_object_term_cache($post->ID, 'post'); } else { clean_post_cache($post->ID); } } unset($postRes); unset($prioProvider); if ($this->GetOption("b_safemode") !== true && $con) { mysql_close($con); } } if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: End Postings")); } } //Add the cats if ($this->GetOption("in_cats")) { if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Start Cats")); } $exclCats = $this->GetOption("b_exclude_cats"); // Excluded cats if ($exclCats == null) { $exclCats = array(); } if (!$this->IsTaxonomySupported()) { $catsRes = $nxtdb->get_results("\r\n\t\t\t\t\t\t\tSELECT\r\n\t\t\t\t\t\t\t\tc.cat_ID AS ID,\r\n\t\t\t\t\t\t\t\tMAX(p.post_modified_gmt) AS last_mod\r\n\t\t\t\t\t\t\tFROM\r\n\t\t\t\t\t\t\t\t`" . $nxtdb->categories . "` c,\r\n\t\t\t\t\t\t\t\t`" . $nxtdb->post2cat . "` pc,\r\n\t\t\t\t\t\t\t\t`" . $nxtdb->posts . "` p\r\n\t\t\t\t\t\t\tWHERE\r\n\t\t\t\t\t\t\t\tpc.category_id = c.cat_ID\r\n\t\t\t\t\t\t\t\tAND p.ID = pc.post_id\r\n\t\t\t\t\t\t\t\tAND p.post_status = 'publish'\r\n\t\t\t\t\t\t\t\tAND p.post_type='post'\r\n\t\t\t\t\t\t\tGROUP\r\n\t\t\t\t\t\t\t\tBY c.cat_id\r\n\t\t\t\t\t\t\t"); if ($catsRes) { foreach ($catsRes as $cat) { if ($cat && $cat->ID && $cat->ID > 0 && !in_array($cat->ID, $exclCats)) { if ($debug) { if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Cat-ID:" . $cat->ID)); } } if (!$qt["enabled"]) { $this->AddUrl(get_category_link($cat->ID), $this->GetTimestampFromMySql($cat->last_mod), $this->GetOption("cf_cats"), $this->GetOption("pr_cats")); } qt_permalink($qt, get_category_link($cat->ID), null, $cat->last_mod, $this->GetOption("cf_cats"), $this->GetOption("pr_cats"), $this); } } } } else { $cats = get_terms("category", array("hide_empty" => true, "hierarchical" => false)); if ($cats && is_array($cats) && count($cats) > 0) { foreach ($cats as $cat) { if (!in_array($cat->term_id, $exclCats)) { if (!$qt["enabled"]) { $this->AddUrl(get_category_link($cat->term_id), 0, $this->GetOption("cf_cats"), $this->GetOption("pr_cats")); } qt_permalink($qt, get_category_link($cat->term_id), null, 0, $this->GetOption("cf_cats"), $this->GetOption("pr_cats"), $this); } } } } if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: End Cats")); } } //Add the archives if ($this->GetOption("in_arch")) { if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Start Archive")); } $now = current_time('mysql'); //nxt2.1 introduced post_status='future', for earlier nxt versions we need to check the post_date_gmt $arcresults = $nxtdb->get_results("\r\n\t\t\t\t\t\tSELECT DISTINCT\r\n\t\t\t\t\t\t\tYEAR(post_date_gmt) AS `year`,\r\n\t\t\t\t\t\t\tMONTH(post_date_gmt) AS `month`,\r\n\t\t\t\t\t\t\tMAX(post_date_gmt) as last_mod,\r\n\t\t\t\t\t\t\tcount(ID) as posts\r\n\t\t\t\t\t\tFROM\r\n\t\t\t\t\t\t\t{$nxtdb->posts}\r\n\t\t\t\t\t\tWHERE\r\n\t\t\t\t\t\t\tpost_date < '{$now}'\r\n\t\t\t\t\t\t\tAND post_status = 'publish'\r\n\t\t\t\t\t\t\tAND post_type = 'post'\r\n\t\t\t\t\t\t\t" . (floatval($nxt_version) < 2.1 ? "AND {$nxtdb->posts}.post_date_gmt <= '" . gmdate('Y-m-d H:i:59') . "'" : "") . "\r\n\t\t\t\t\t\tGROUP BY\r\n\t\t\t\t\t\t\tYEAR(post_date_gmt),\r\n\t\t\t\t\t\t\tMONTH(post_date_gmt)\r\n\t\t\t\t\t\tORDER BY\r\n\t\t\t\t\t\t\tpost_date_gmt DESC"); if ($arcresults) { foreach ($arcresults as $arcresult) { $url = get_month_link($arcresult->year, $arcresult->month); $changeFreq = ""; //Archive is the current one if ($arcresult->month == date("n") && $arcresult->year == date("Y")) { $changeFreq = $this->GetOption("cf_arch_curr"); } else { // Archive is older $changeFreq = $this->GetOption("cf_arch_old"); } if (!$qt["enabled"]) { $this->AddUrl($url, $this->GetTimestampFromMySql($arcresult->last_mod), $changeFreq, $this->GetOption("pr_arch")); } qt_permalink($qt, $url, null, $arcresult->last_mod, $changeFreq, $this->GetOption("pr_arch"), $this); } } if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: End Archive")); } } //Add the author pages if ($this->GetOption("in_auth")) { if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Start Author pages")); } $linkFunc = null; //get_author_link is deprecated in nxt 2.1, try to use get_author_posts_url first. if (function_exists('get_author_posts_url')) { $linkFunc = 'get_author_posts_url'; } else { if (function_exists('get_author_link')) { $linkFunc = 'get_author_link'; } } //Who knows what happens in later nxt versions, so check again if it worked if ($linkFunc !== null) { //Unfortunately there is no API function to get all authors, so we have to do it the dirty way... //We retrieve only users with published and not password protected posts (and not pages) //nxt2.1 introduced post_status='future', for earlier nxt versions we need to check the post_date_gmt $sql = "SELECT DISTINCT\r\n\t\t\t\t\t\t\tu.ID,\r\n\t\t\t\t\t\t\tu.user_nicename,\r\n\t\t\t\t\t\t\tMAX(p.post_modified_gmt) AS last_post\r\n\t\t\t\t\t\tFROM\r\n\t\t\t\t\t\t\t{$nxtdb->users} u,\r\n\t\t\t\t\t\t\t{$nxtdb->posts} p\r\n\t\t\t\t\t\tWHERE\r\n\t\t\t\t\t\t\tp.post_author = u.ID\r\n\t\t\t\t\t\t\tAND p.post_status = 'publish'\r\n\t\t\t\t\t\t\tAND p.post_type = 'post'\r\n\t\t\t\t\t\t\tAND p.post_password = ''\r\n\t\t\t\t\t\t\t" . (floatval($nxt_version) < 2.1 ? "AND p.post_date_gmt <= '" . gmdate('Y-m-d H:i:59') . "'" : "") . "\r\n\t\t\t\t\t\tGROUP BY\r\n\t\t\t\t\t\t\tu.ID,\r\n\t\t\t\t\t\t\tu.user_nicename"; $authors = $nxtdb->get_results($sql); if ($authors && is_array($authors)) { foreach ($authors as $author) { if ($debug) { if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Author-ID:" . $author->ID)); } } $url = $linkFunc == 'get_author_posts_url' ? get_author_posts_url($author->ID, $author->user_nicename) : get_author_link(false, $author->ID, $author->user_nicename); if (!$qt["enabled"]) { $this->AddUrl($url, $this->GetTimestampFromMySql($author->last_post), $this->GetOption("cf_auth"), $this->GetOption("pr_auth")); } qt_permalink($qt, $url, null, $author->last_post, $this->GetOption("cf_auth"), $this->GetOption("pr_auth"), $this); } } } else { //Too bad, no author pages for you :( if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: No valid author link function found")); } } if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: End Author pages")); } } //Add tag pages if ($this->GetOption("in_tags") && $this->IsTaxonomySupported()) { if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Start Tags")); } $tags = get_terms("post_tag", array("hide_empty" => true, "hierarchical" => false)); if ($tags && is_array($tags) && count($tags) > 0) { foreach ($tags as $tag) { if (!$qt["enabled"]) { $this->AddUrl(get_tag_link($tag->term_id), 0, $this->GetOption("cf_tags"), $this->GetOption("pr_tags")); } qt_permalink($qt, get_tag_link($tag->term_id), null, 0, $this->GetOption("cf_tags"), $this->GetOption("pr_tags"), $this); } } if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: End Tags")); } } //Add custom taxonomy pages if ($this->GetOption("in_tax") && $this->IsTaxonomySupported()) { if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Start custom taxonomies")); } $enabledTaxonomies = $this->GetOption("in_tax"); $taxList = array(); foreach ($enabledTaxonomies as $taxName) { $taxonomy = get_taxonomy($taxName); if ($taxonomy) { $taxList[] = $nxtdb->escape($taxonomy->name); } } if (count($taxList) > 0) { //We're selecting all term information (t.*) plus some additional fields //like the last mod date and the taxonomy name, so nxt doesnt need to make //additional queries to build the permalink structure. //This does NOT work for categories and tags yet, because nxt uses get_category_link //and get_tag_link internally and that would cause one additional query per term! $sql = "\r\n\t\t\t\t\tSELECT\r\n\t\t\t\t\t\tt.*,\r\n\t\t\t\t\t\ttt.taxonomy AS _taxonomy,\r\n\t\t\t\t\t\tUNIX_TIMESTAMP(MAX(post_date_gmt)) as _mod_date\r\n\t\t\t\t\tFROM\r\n\t\t\t\t\t\t{$nxtdb->posts} p ,\r\n\t\t\t\t\t\t{$nxtdb->term_relationships} r,\r\n\t\t\t\t\t\t{$nxtdb->terms} t,\r\n\t\t\t\t\t\t{$nxtdb->term_taxonomy} tt\r\n\t\t\t\t\tWHERE\r\n\t\t\t\t\t\tp.ID = r.object_id\r\n\t\t\t\t\t\tAND p.post_status = 'publish'\r\n\t\t\t\t\t\tAND p.post_type = 'post'\r\n\t\t\t\t\t\tAND p.post_password = ''\r\n\t\t\t\t\t\tAND r.term_taxonomy_id = t.term_id\r\n\t\t\t\t\t\tAND t.term_id = tt.term_id\r\n\t\t\t\t\t\tAND tt.count > 0\r\n\t\t\t\t\t\tAND tt.taxonomy IN ('" . implode("','", $taxList) . "')\r\n\t\t\t\t\tGROUP BY\r\n\t\t\t\t\t\tt.term_id"; $termInfo = $nxtdb->get_results($sql); foreach ($termInfo as $term) { $this->AddUrl(get_term_link($term, $term->_taxonomy), $term->_mod_date, $this->GetOption("cf_tags"), $this->GetOption("pr_tags")); } } if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: End custom taxonomies")); } } //Add the custom pages if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Start Custom Pages")); } if ($this->_pages && is_array($this->_pages) && count($this->_pages) > 0) { //#type $page GoogleSitemapGeneratorPage foreach ($this->_pages as $page) { $this->AddUrl($page->GetUrl(), $page->getLastMod(), $page->getChangeFreq(), $page->getPriority()); } } if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: End Custom Pages")); } if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Start additional URLs")); } do_action('sm_buildmap'); if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: End additional URLs")); } $this->AddElement(new GoogleSitemapGeneratorXmlEntry("</urlset>")); $pingUrl = ''; if ($this->GetOption("b_xml")) { if ($this->_fileHandle && fclose($this->_fileHandle)) { $this->_fileHandle = null; $status->EndXml(true); $pingUrl = $this->GetXmlUrl(); } else { $status->EndXml(false, "Could not close the sitemap file."); } } if ($this->IsGzipEnabled()) { if ($this->_fileZipHandle && fclose($this->_fileZipHandle)) { $this->_fileZipHandle = null; $status->EndZip(true); $pingUrl = $this->GetZipUrl(); } else { $status->EndZip(false, "Could not close the zipped sitemap file"); } } //Ping Google if ($this->GetOption("b_ping") && !empty($pingUrl)) { $sPingUrl = "http://www.google.com/webmasters/sitemaps/ping?sitemap=" . urlencode($pingUrl); $status->StartGooglePing($sPingUrl); $pingres = $this->RemoteOpen($sPingUrl); if ($pingres == NULL || $pingres === false) { $status->EndGooglePing(false, $this->_lastError); trigger_error("Failed to ping Google: " . htmlspecialchars(strip_tags($pingres)), E_USER_NOTICE); } else { $status->EndGooglePing(true); } } //Ping Ask.com if ($this->GetOption("b_pingask") && !empty($pingUrl)) { $sPingUrl = "http://submissions.ask.com/ping?sitemap=" . urlencode($pingUrl); $status->StartAskPing($sPingUrl); $pingres = $this->RemoteOpen($sPingUrl); if ($pingres == NULL || $pingres === false || strpos($pingres, "successfully received and added") === false) { //Ask.com returns 200 OK even if there was an error, so we need to check the content. $status->EndAskPing(false, $this->_lastError); trigger_error("Failed to ping Ask.com: " . htmlspecialchars(strip_tags($pingres)), E_USER_NOTICE); } else { $status->EndAskPing(true); } } //Ping Bing if ($this->GetOption("b_pingmsn") && !empty($pingUrl)) { $sPingUrl = "http://www.bing.com/webmaster/ping.aspx?siteMap=" . urlencode($pingUrl); $status->StartMsnPing($sPingUrl); $pingres = $this->RemoteOpen($sPingUrl); //Bing returns ip/country-based success messages, so there is no way to check the content. Rely on HTTP 500 only then... if ($pingres == NULL || $pingres === false || strpos($pingres, " ") === false) { trigger_error("Failed to ping Bing: " . htmlspecialchars(strip_tags($pingres)), E_USER_NOTICE); $status->EndMsnPing(false, $this->_lastError); } else { $status->EndMsnPing(true); } } $status->End(); $this->_isActive = false; //done... return $status; }
/** * posts() * * @return void **/ function posts() { global $wpdb; $sql = "\n\t\t\tSELECT\tposts.ID,\n\t\t\t\t\tposts.post_author,\n\t\t\t\t\tposts.post_name,\n\t\t\t\t\tposts.post_type,\n\t\t\t\t\tposts.post_status,\n\t\t\t\t\tposts.post_parent,\n\t\t\t\t\tposts.post_date,\n\t\t\t\t\tposts.post_modified,\n\t\t\t\t\tCAST(posts.post_modified AS DATE) as lastmod,\n\t\t\t\t\tCASE COUNT(DISTINCT CAST(revisions.post_date AS DATE))\n\t\t\t\t\tWHEN 0\n\t\t\t\t\tTHEN\n\t\t\t\t\t\t0\n\t\t\t\t\tELSE\n\t\t\t\t\t\tDATEDIFF(CAST(NOW() AS DATE), CAST(posts.post_date AS DATE))\n\t\t\t\t\t\t/ COUNT(DISTINCT CAST(revisions.post_date AS DATE))\n\t\t\t\t\tEND as changefreq\n\t\t\tFROM\t{$wpdb->posts} as posts\n\t\t\tLEFT JOIN {$wpdb->posts} as revisions\n\t\t\tON\t\trevisions.post_parent = posts.ID\n\t\t\tAND\t\trevisions.post_type = 'revision'\n\t\t\tAND\t\tDATEDIFF(CAST(revisions.post_date AS DATE), CAST(posts.post_date AS DATE)) > 2\n\t\t\tAND\t\tDATE_SUB(CAST(NOW() AS DATE), INTERVAL 1 YEAR) < CAST(revisions.post_date AS DATE)\n\t\t\tLEFT JOIN {$wpdb->postmeta} as redirect_url\n\t\t\tON\t\tredirect_url.post_id = posts.ID\n\t\t\tAND\t\tredirect_url.meta_key = '_redirect_url'\n\t\t\tLEFT JOIN {$wpdb->postmeta} as widgets_exclude\n\t\t\tON\t\twidgets_exclude.post_id = posts.ID\n\t\t\tAND\t\twidgets_exclude.meta_key = '_widgets_exclude'\n\t\t\tLEFT JOIN {$wpdb->postmeta} as widgets_exception\n\t\t\tON\t\twidgets_exception.post_id = posts.ID\n\t\t\tAND\t\twidgets_exception.meta_key = '_widgets_exception'\n\t\t\tWHERE\tposts.post_type = 'post'\n\t\t\tAND\t\tposts.post_status = 'publish'\n\t\t\tAND\t\tposts.post_password = ''\n\t\t\tAND\t\tredirect_url.post_id IS NULL\n\t\t\tAND\t\t( widgets_exclude.post_id IS NULL OR widgets_exception.post_id IS NOT NULL )\n\t\t\tGROUP BY posts.ID\n\t\t\tORDER BY posts.post_parent, posts.ID\n\t\t\t"; #dump($sql); $posts = $wpdb->get_results($sql); update_post_cache($posts); foreach ($posts as $post) { $this->write(apply_filters('the_permalink', get_permalink($post->ID)), $post->lastmod, $post->changefreq, 0.6); } }
function redo_search($the_posts = array()) { global $wpdb; global $wp_query; if (is_search()) { $GLOBALS['sem_s'] = get_query_var('s'); preg_match_all("/((\\w|-)+)/", $GLOBALS['sem_s'], $out); $keywords = current($out); if (empty($keywords)) { return array(); } $query_string = ""; $keyword_filter = ""; foreach ($keywords as $keyword) { $query_string .= ($query_string ? " " : "") . $keyword; $reg_one_present .= ($reg_one_present ? "|" : "") . $keyword; } $paged = $wp_query->get('paged'); if (!$paged) { $paged = 1; } $posts_per_page = $wp_query->get('posts_per_page'); if (!$posts_per_page) { $posts_per_page = get_settings('posts_per_page'); } $offset = ($paged - 1) * $posts_per_page; $now = gmdate('Y-m-d H:i:00', strtotime("+1 minute")); if (isset($GLOBALS['sem_static_front'])) { $GLOBALS['sem_static_front']->init(); } if (isset($GLOBALS['sem_sidebar_tile'])) { $GLOBALS['sem_sidebar_tile']->init(); } $search_query = "\r\n\t\t\t\tSELECT\r\n\t\t\t\t\tDISTINCT posts.*,\r\n\t\t\t\t\tCASE\r\n\t\t\t\t\t\tWHEN posts.post_title REGEXP '{$reg_one_present}'\r\n\t\t\t\t\t\t\tTHEN 1\r\n\t\t\t\t\t\t\tELSE 0\r\n\t\t\t\t\t\tEND AS keyword_in_title,\r\n\t\t\t\t\tMATCH ( posts.post_title, posts.post_content )\r\n\t\t\t\t\t\tAGAINST ( '" . addslashes($query_string) . "' ) AS mysql_score\r\n\t\t\t\tFROM\r\n\t\t\t\t\t{$wpdb->posts} as posts\r\n\t\t\t\tLEFT JOIN {$wpdb->postmeta} as postmeta\r\n\t\t\t\t\tON postmeta.post_id = posts.ID\r\n\t\t\t\tWHERE\r\n\t\t\t\t\tposts.post_date_gmt <= '" . $now . "'" . (defined('sem_home_page_id') && sem_home_page_id ? "\r\n\t\t\t\t\tAND posts.ID <> " . intval(sem_home_page_id) : "") . (defined('sem_sidebar_tile_id') && sem_sidebar_tile_id ? "\r\n\t\t\t\t\tAND posts.ID <> " . intval(sem_sidebar_tile_id) : "") . "\r\n\t\t\t\t\tAND ( posts.post_password = '' )\r\n\t\t\t\t\tAND ( " . (function_exists('get_site_option') ? "( post_status = 'publish' AND ( post_type = 'post' OR ( post_type = 'page' AND postmeta.meta_value = 'article.php' ) ) )" : "( post_status = 'publish' OR ( post_status = 'static' AND postmeta.meta_value = 'article.php' ) )") . " )\r\n\t\t\t\t\tAND ( posts.post_title REGEXP '{$reg_one_present}' OR posts.post_content REGEXP '{$reg_one_present}' )\r\n\t\t\t\tGROUP BY\r\n\t\t\t\t\tposts.ID\r\n\t\t\t\tORDER BY\r\n\t\t\t\t\tkeyword_in_title DESC, mysql_score DESC, posts.post_date DESC\r\n\t\t\t\tLIMIT " . intval($offset) . ", " . intval($posts_per_page); $request_query = "\r\n\t\t\t\tSELECT\r\n\t\t\t\t\tDISTINCT posts.*\r\n\t\t\t\tFROM\r\n\t\t\t\t\t{$wpdb->posts} as posts\r\n\t\t\t\tLEFT JOIN {$wpdb->postmeta} as postmeta\r\n\t\t\t\t\tON postmeta.post_id = posts.ID\r\n\t\t\t\tWHERE\r\n\t\t\t\t\tposts.post_date_gmt <= '" . $now . "'" . (defined('sem_home_page_id') && sem_home_page_id ? "\r\n\t\t\t\t\tAND posts.ID <> " . intval(sem_home_page_id) : "") . (defined('sem_sidebar_tile_id') && sem_sidebar_tile_id ? "\r\n\t\t\t\t\tAND posts.ID <> " . intval(sem_sidebar_tile_id) : "") . "\r\n\t\t\t\t\tAND ( posts.post_password = '' )\r\n\t\t\t\t\tAND ( " . (function_exists('get_site_option') ? "( post_status = 'publish' AND ( post_type = 'post' OR ( post_type = 'page' AND postmeta.meta_value = 'article.php' ) ) )" : "( post_status = 'publish' OR ( post_status = 'static' AND postmeta.meta_value = 'article.php' ) )") . " )\r\n\t\t\t\t\tAND ( posts.post_title REGEXP '{$reg_one_present}' OR posts.post_content REGEXP '{$reg_one_present}' )\r\n\t\t\t\tGROUP BY\r\n\t\t\t\t\tposts.ID\r\n\t\t\t\tLIMIT " . intval($offset) . ", " . intval($posts_per_page); $the_posts = $wpdb->get_results($search_query); $GLOBALS['request'] = ' ' . preg_replace("/[\n\r\\s]+/", " ", $request_query) . ' '; if (function_exists('update_post_cache')) { update_post_cache($the_posts); } if (function_exists('update_page_cache')) { update_page_cache($the_posts); } } return $the_posts; }
/** * get_posts() * * @param string $query * @return array $results **/ function get_posts($query) { global $wp_query; $results = false; if ($wp_query->is_preview || $wp_query->is_robots || isset($_GET['trashed'])) { # bail: we don't want to cache this stuff return $results; } if ($wp_query->is_singular) { $post_id = wp_cache_get(self::$cache_id, 'url2post_id'); if ($post_id === 0) { $results = array(); $this->cache_hits++; } elseif ($post_id) { $post = wp_cache_get($post_id, 'posts'); if ($post !== false) { $results = array($post); $this->cache_hits++; } } if ($results !== false) { return $results; } if (isset($_GET['action']) || isset($_GET['doing_wp_cron']) || isset($_GET['debug']) || isset($_GET['preview']) || defined('WP_INSTALLING') && WP_INSTALLING || defined('WP_ADMIN') && WP_ADMIN || defined('DOING_CRON') && DOING_CRON || defined('DOING_AJAX') && DOING_AJAX || $_POST) { return $results; } $results = self::$wpdb->get_results($query); if ($results) { update_post_cache($results); $post_id = $results[0]->ID; } else { $post_id = 0; } if (!$post_id || $wp_query->is_feed) { $timeout = min(3600, cache_timeout); } elseif ($wp_query->is_paged || self::$cache_id != md5(get_permalink($post_id))) { $timeout = cache_timeout; } else { $timeout = 0; } wp_cache_add(self::$cache_id, $post_id, 'url2post_id', $timeout); } else { if (!$wp_query->is_singular && is_user_logged_in()) { $query = self::maybe_strip_private_posts($query); } if (strpos($query, "'private'") !== false) { # bail: queries that return private posts can't be efficiently cached return $results; } $posts = wp_cache_get(self::$cache_id, 'url2posts'); $found = wp_cache_get(self::$cache_id, 'url2posts_found'); if ($posts !== false && $found !== false) { $results = $posts; self::$found = $found; $this->cache_hits++; return $results; } if (isset($_GET['action']) || isset($_GET['doing_wp_cron']) || isset($_GET['debug']) || isset($_GET['preview']) || defined('WP_INSTALLING') && WP_INSTALLING || defined('WP_ADMIN') && WP_ADMIN || defined('DOING_CRON') && DOING_CRON || defined('DOING_AJAX') && DOING_AJAX || $_POST) { return $results; } if ($wp_query->is_home || $wp_query->is_category || $wp_query->is_tag || $wp_query->is_author || $wp_query->is_date || $wp_query->is_feed && !$wp_query->is_singular && !$wp_query->is_archive) { $results = self::$wpdb->get_results($query); self::$found = self::$wpdb->get_var("SELECT FOUND_ROWS()"); if (!$results || $wp_query->is_feed || redirect_canonical(null, false)) { $timeout = min(3600, cache_timeout); } elseif ($wp_query->is_paged) { $timeout = cache_timeout; } else { $timeout = 0; } wp_cache_add(self::$cache_id, $results, 'url2posts', $timeout); wp_cache_add(self::$cache_id, self::$found, 'url2posts_found', $timeout); } } return $results; }
function flt_get_pages($results, $args = array()) { $results = (array) $results; global $wpdb; // === BEGIN Role Scoper ADDITION: global var; various special case exemption checks === // global $scoper, $current_rs_user; // need to skip cache retrieval if QTranslate is filtering get_pages with a priority of 1 or less $no_cache = !defined('SCOPER_QTRANSLATE_COMPAT') && awp_is_plugin_active('qtranslate'); // buffer titles in case they were filtered previously $titles = scoper_get_property_array($results, 'ID', 'post_title'); // depth is not really a get_pages arg, but remap exclude arg to exclude_tree if wp_list_terms called with depth=1 if (!empty($args['exclude']) && empty($args['exclude_tree']) && !empty($args['depth']) && 1 == $args['depth']) { if (0 !== strpos($args['exclude'], ',')) { // work around wp_list_pages() bug of attaching leading comma if a plugin uses wp_list_pages_excludes filter $args['exclude_tree'] = $args['exclude']; } } // // === END Role Scoper ADDITION === // ================================= $defaults = array('child_of' => 0, 'sort_order' => 'ASC', 'sort_column' => 'post_title', 'hierarchical' => 1, 'exclude' => array(), 'include' => array(), 'meta_key' => '', 'meta_value' => '', 'authors' => '', 'parent' => -1, 'exclude_tree' => '', 'number' => '', 'offset' => 0, 'post_type' => 'page', 'post_status' => 'publish', 'depth' => 0, 'suppress_filters' => 0, 'remap_parents' => -1, 'enforce_actual_depth' => -1, 'remap_thru_excluded_parent' => -1); // Role Scoper arguments added above // === BEGIN Role Scoper ADDITION: support front-end optimization $post_type = isset($args['post_type']) ? $args['post_type'] : $defaults['post_type']; $use_post_types = (array) scoper_get_option('use_post_types'); if (empty($use_post_types[$post_type])) { return $results; } if ($scoper->is_front()) { if ('page' == $post_type && defined('SCOPER_GET_PAGES_LEAN')) { // custom types are likely to have custom fields $defaults['fields'] = "{$wpdb->posts}.ID, {$wpdb->posts}.post_title, {$wpdb->posts}.post_parent, {$wpdb->posts}.post_date, {$wpdb->posts}.post_date_gmt, {$wpdb->posts}.post_status, {$wpdb->posts}.post_name, {$wpdb->posts}.post_modified, {$wpdb->posts}.post_modified_gmt, {$wpdb->posts}.guid, {$wpdb->posts}.menu_order, {$wpdb->posts}.comment_count"; } else { $defaults['fields'] = "{$wpdb->posts}.*"; if (!defined('SCOPER_FORCE_PAGES_CACHE')) { $no_cache = true; } // serialization / unserialization of post_content for all pages is too memory-intensive for sites with a lot of pages } } else { // required for xmlrpc getpagelist method $defaults['fields'] = "{$wpdb->posts}.*"; if (!defined('SCOPER_FORCE_PAGES_CACHE')) { $no_cache = true; } } // === END Role Scoper MODIFICATION === $r = wp_parse_args($args, $defaults); extract($r, EXTR_SKIP); $number = (int) $number; $offset = (int) $offset; $child_of = (int) $child_of; // Role Scoper modification: null value will confuse children array check // Make sure the post type is hierarchical $hierarchical_post_types = get_post_types(array('public' => true, 'hierarchical' => true)); if (!in_array($post_type, $hierarchical_post_types)) { return $results; } // Make sure we have a valid post status if (!in_array($post_status, get_post_stati())) { return $results; } // for the page parent dropdown, return no available selections for a published main page if the logged user isn't allowed to de-associate it from Main if (!empty($name) && 'parent_id' == $name) { global $post; if ('no_parent_filter' == scoper_get_option('lock_top_pages')) { return $results; } if (!$post->post_parent && !$GLOBALS['scoper_admin_filters']->user_can_associate_main($post_type)) { $status_obj = get_post_status_object($post->post_status); if ($status_obj->public || $status_obj->private) { return array(); } } if (!empty($post) && $post_type == $post->post_type) { if ($post->post_parent) { $append_page = get_post($post->post_parent); } $exclude_tree = $post->ID; } } //$scoper->last_get_pages_args = $r; // don't copy entire args array unless it proves necessary $scoper->last_get_pages_depth = $depth; $scoper->last_get_pages_suppress_filters = $suppress_filters; if ($suppress_filters) { return $results; } // === BEGIN Role Scoper MODIFICATION: wp-cache key and flag specific to access type and user/groups // if (!scoper_get_otype_option('use_object_roles', 'post', $post_type)) { return $results; } $key = md5(serialize(compact(array_keys($defaults)))); $ckey = md5($key . CURRENT_ACCESS_NAME_RS); $cache_flag = 'rs_get_pages'; $cache = $current_rs_user->cache_get($cache_flag); if (false !== $cache) { if (!is_array($cache)) { $cache = array(); } if (!$no_cache && isset($cache[$ckey])) { // alternate filter name (WP core already applied get_pages filter) return apply_filters('get_pages_rs', $cache[$ckey], $r); } } // // === END Role Scoper MODIFICATION === // ==================================== $inclusions = ''; if (!empty($include)) { $child_of = 0; //ignore child_of, parent, exclude, meta_key, and meta_value params if using include $parent = -1; $exclude = ''; $meta_key = ''; $meta_value = ''; $hierarchical = false; $incpages = wp_parse_id_list($include); if (!empty($incpages)) { foreach ($incpages as $incpage) { if (empty($inclusions)) { $inclusions = ' AND ( ID = ' . intval($incpage) . ' '; } else { $inclusions .= ' OR ID = ' . intval($incpage) . ' '; } } } } if (!empty($inclusions)) { $inclusions .= ')'; } $exclusions = ''; if (!empty($exclude)) { $expages = wp_parse_id_list($exclude); if (!empty($expages)) { foreach ($expages as $expage) { if (empty($exclusions)) { $exclusions = ' AND ( ID <> ' . intval($expage) . ' '; } else { $exclusions .= ' AND ID <> ' . intval($expage) . ' '; } } } } if (!empty($exclusions)) { $exclusions .= ')'; } $author_query = ''; if (!empty($authors)) { $post_authors = wp_parse_id_list($authors); if (!empty($post_authors)) { foreach ($post_authors as $post_author) { //Do we have an author id or an author login? if (0 == intval($post_author)) { $post_author = get_userdatabylogin($post_author); if (empty($post_author)) { continue; } if (empty($post_author->ID)) { continue; } $post_author = $post_author->ID; } if ('' == $author_query) { $author_query = ' post_author = ' . intval($post_author) . ' '; } else { $author_query .= ' OR post_author = ' . intval($post_author) . ' '; } } if ('' != $author_query) { $author_query = " AND ({$author_query})"; } } } $join = ''; $where = "{$exclusions} {$inclusions} "; if (!empty($meta_key) || !empty($meta_value)) { $join = " INNER JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id"; // Role Scoper modification: was LEFT JOIN in WP 3.0 core (TODO: would that botch uro join results? // meta_key and meta_value might be slashed $meta_key = stripslashes($meta_key); $meta_value = stripslashes($meta_value); if (!empty($meta_key)) { $where .= $wpdb->prepare(" AND {$wpdb->postmeta}.meta_key = %s", $meta_key); } if (!empty($meta_value)) { $where .= $wpdb->prepare(" AND {$wpdb->postmeta}.meta_value = %s", $meta_value); } } if ($parent >= 0) { $where .= $wpdb->prepare(' AND post_parent = %d ', $parent); } // === BEGIN Role Scoper MODIFICATION: // allow pages of multiple statuses to be displayed (requires default status=publish to be ignored) // $where_post_type = $wpdb->prepare("post_type = '%s'", $post_type); $where_status = ''; $is_front = $scoper->is_front(); $is_teaser_active = $scoper->is_front() && scoper_get_otype_option('do_teaser', 'post') && scoper_get_otype_option('use_teaser', 'post', $post_type); $private_teaser = $is_teaser_active && scoper_get_otype_option('use_teaser', 'post', $post_type) && !scoper_get_otype_option('teaser_hide_private', 'post', $post_type); if ($is_front && (!empty($current_rs_user->ID) || $private_teaser)) { $frontend_list_private = scoper_get_otype_option('private_items_listable', 'post', 'page'); } else { $frontend_list_private = false; } $force_publish_status = !$frontend_list_private && 'publish' == $post_status; // WP core does not include private pages in query. Include private statuses in anticipation of user-specific filtering if ($post_status && ('publish' != $post_status || $is_front && !$frontend_list_private)) { $where_status = $wpdb->prepare("post_status = '%s'", $post_status); } else { // since we will be applying status clauses based on content-specific roles and restrictions, only a sanity check safeguard is needed when post_status is unspecified or defaulted to "publish" $safeguard_statuses = array(); foreach (get_post_stati(array('internal' => false), 'object') as $status_name => $status_obj) { if (!$is_front || $status_obj->private || $status_obj->public) { $safeguard_statuses[] = $status_name; } } $where_status = "post_status IN ('" . implode("','", $safeguard_statuses) . "')"; } $query = "SELECT {$fields} FROM {$wpdb->posts} {$join} WHERE 1=1 AND {$where_post_type} AND ( {$where_status} {$where} {$author_query} ) ORDER BY {$sort_column} {$sort_order}"; if (!empty($number)) { $query .= ' LIMIT ' . $offset . ',' . $number; } if ($is_teaser_active && !defined('SCOPER_TEASER_HIDE_PAGE_LISTING')) { // We are in the front end and the teaser is enabled for pages $query = apply_filters('objects_request_rs', $query, 'post', $post_type, array('force_teaser' => true)); $pages = scoper_get_results($query); // execute unfiltered query // Pass results of unfiltered query through the teaser filter. // If listing private pages is disabled, they will be omitted completely, but restricted published pages // will still be teased. This is a slight design compromise to satisfy potentially conflicting user goals without yet another option $pages = apply_filters('objects_results_rs', $pages, 'post', (array) $post_type, array('request' => $query, 'force_teaser' => true, 'object_type' => $post_type)); // restore buffered titles in case they were filtered previously scoper_restore_property_array($pages, $titles, 'ID', 'post_title'); $pages = apply_filters('objects_teaser_rs', $pages, 'post', $post_type, array('request' => $query, 'force_teaser' => true)); if ($frontend_list_private) { if (!scoper_get_otype_option('teaser_hide_private', 'post', $post_type)) { $tease_all = true; } } } else { $_args = array('skip_teaser' => true, 'retain_status' => $force_publish_status); if (in_array($GLOBALS['pagenow'], array('post.php', 'post-new.php'))) { if ($post_type_obj = get_post_type_object($post_type)) { $plural_name = plural_name_from_cap_rs($post_type_obj); $_args['alternate_reqd_caps'][0] = array("create_child_{$plural_name}"); } } // Pass query through the request filter $query = apply_filters('objects_request_rs', $query, 'post', $post_type, $_args); // Execute the filtered query $pages = scoper_get_results($query); // restore buffered titles in case they were filtered previously scoper_restore_property_array($pages, $titles, 'ID', 'post_title'); } if (empty($pages)) { // alternate hook name (WP core already applied get_pages filter) return apply_filters('get_pages_rs', array(), $r); } // // === END Role Scoper MODIFICATION === // ==================================== // Role Scoper note: WP core get_pages has already updated wp_cache and pagecache with unfiltered results. update_post_cache($pages); // === BEGIN Role Scoper MODIFICATION: Support a disjointed pages tree with some parents hidden ======== if ($child_of || empty($tease_all)) { // if we're including all pages with teaser, no need to continue thru tree remapping $ancestors = ScoperAncestry::get_page_ancestors(); // array of all ancestor IDs for keyed page_id, with direct parent first $orderby = $sort_column; if ($parent > 0 || !$hierarchical) { $remap_parents = false; } else { // if these settings were passed into this get_pages call, use them if (-1 === $remap_parents) { $remap_parents = scoper_get_option('remap_page_parents'); } if ($remap_parents) { if (-1 === $enforce_actual_depth) { $enforce_actual_depth = scoper_get_option('enforce_actual_page_depth'); } if (-1 === $remap_thru_excluded_parent) { $remap_thru_excluded_parent = scoper_get_option('remap_thru_excluded_page_parent'); } } } $remap_args = compact('child_of', 'parent', 'exclude', 'depth', 'orderby', 'remap_parents', 'enforce_actual_depth', 'remap_thru_excluded_parent'); // one or more of these args may have been modified after extraction ScoperHardway::remap_tree($pages, $ancestors, 'ID', 'post_parent', $remap_args); } // === END Role Scoper MODIFICATION === // ==================================== if (!empty($exclude_tree)) { $exclude = array(); $exclude = (int) $exclude_tree; $children = get_page_children($exclude, $pages); // RS note: okay to use unfiltered function here since it's only used for excluding $excludes = array(); foreach ($children as $child) { $excludes[] = $child->ID; } $excludes[] = $exclude; $total = count($pages); for ($i = 0; $i < $total; $i++) { if (in_array($pages[$i]->ID, $excludes)) { unset($pages[$i]); } } } if (!empty($append_page) && !empty($pages)) { $found = false; foreach (array_keys($pages) as $key) { if ($post->post_parent == $pages[$key]->ID) { $found = true; break; } } if (empty($found)) { $pages[] = $append_page; } } // re-index the array, just in case anyone cares $pages = array_values($pages); // === BEGIN Role Scoper MODIFICATION: cache key and flag specific to access type and user/groups // if (!$no_cache) { $cache[$ckey] = $pages; $current_rs_user->cache_set($cache, $cache_flag); } // alternate hook name (WP core already applied get_pages filter) $pages = apply_filters('get_pages_rs', $pages, $r); // // === END Role Scoper MODIFICATION === // ==================================== return $pages; }
/** * Retrieve a list of pages. * * @global hqdb $hqdb HiveQueen database abstraction object. * * @since 0.0.1 * * @param array|string $args { * Optional. Array or string of arguments to retrieve pages. * * @type int $child_of Page ID to return child and grandchild pages of. * Default 0, or no restriction. * @type string $sort_order How to sort retrieved pages. Accepts 'ASC', 'DESC'. Default 'ASC'. * @type string $sort_column What columns to sort pages by, comma-separated. Accepts 'post_author', * 'post_date', 'post_title', 'post_name', 'post_modified', 'menu_order', * 'post_modified_gmt', 'post_parent', 'ID', 'rand', 'comment_count'. * 'post_' can be omitted for any values that start with it. * Default 'post_title'. * @type bool $hierarchical Whether to return pages hierarchically. Default true. * @type array $exclude Array of page IDs to exclude. Default empty array. * @type array $include Array of page IDs to include. Cannot be used with `$child_of`, * `$parent`, `$exclude`, `$meta_key`, `$meta_value`, or `$hierarchical`. * Default empty array. * @type string $meta_key Only include pages with this meta key. Default empty. * @type string $meta_value Only include pages with this meta value. Requires `$meta_key`. * Default empty. * @type string $authors A comma-separated list of author IDs. Default empty. * @type int $parent Page ID to return direct children of. `$hierarchical` must be false. * Default -1, or no restriction. * @type string|array $exclude_tree Comma-separated string or array of page IDs to exclude. * Default empty array. * @type int $number The number of pages to return. Default 0, or all pages. * @type int $offset The number of pages to skip before returning. Requires `$number`. * Default 0. * @type string $post_type The post type to query. Default 'page'. * @type string $post_status A comma-separated list of post status types to include. * Default 'publish'. * } * @return array|false List of pages matching defaults or `$args`. */ function get_pages($args = array()) { global $hqdb; $defaults = array('child_of' => 0, 'sort_order' => 'ASC', 'sort_column' => 'post_title', 'hierarchical' => 1, 'exclude' => array(), 'include' => array(), 'meta_key' => '', 'meta_value' => '', 'authors' => '', 'parent' => -1, 'exclude_tree' => array(), 'number' => '', 'offset' => 0, 'post_type' => 'page', 'post_status' => 'publish'); $r = hq_parse_args($args, $defaults); $number = (int) $r['number']; $offset = (int) $r['offset']; $child_of = (int) $r['child_of']; $hierarchical = $r['hierarchical']; $exclude = $r['exclude']; $meta_key = $r['meta_key']; $meta_value = $r['meta_value']; $parent = $r['parent']; $post_status = $r['post_status']; // Make sure the post type is hierarchical. $hierarchical_post_types = get_post_types(array('hierarchical' => true)); if (!in_array($r['post_type'], $hierarchical_post_types)) { return false; } if ($parent > 0 && !$child_of) { $hierarchical = false; } // Make sure we have a valid post status. if (!is_array($post_status)) { $post_status = explode(',', $post_status); } if (array_diff($post_status, get_post_stati())) { return false; } // $args can be whatever, only use the args defined in defaults to compute the key. $key = md5(serialize(hq_array_slice_assoc($r, array_keys($defaults)))); $last_changed = hq_cache_get('last_changed', 'posts'); if (!$last_changed) { $last_changed = microtime(); hq_cache_set('last_changed', $last_changed, 'posts'); } $cache_key = "get_pages:{$key}:{$last_changed}"; if ($cache = hq_cache_get($cache_key, 'posts')) { // Convert to HQ_Post instances. $pages = array_map('get_post', $cache); /** This filter is documented in hq-includes/post.php */ $pages = apply_filters('get_pages', $pages, $r); return $pages; } $inclusions = ''; if (!empty($r['include'])) { $child_of = 0; //ignore child_of, parent, exclude, meta_key, and meta_value params if using include $parent = -1; $exclude = ''; $meta_key = ''; $meta_value = ''; $hierarchical = false; $incpages = hq_parse_id_list($r['include']); if (!empty($incpages)) { $inclusions = ' AND ID IN (' . implode(',', $incpages) . ')'; } } $exclusions = ''; if (!empty($exclude)) { $expages = hq_parse_id_list($exclude); if (!empty($expages)) { $exclusions = ' AND ID NOT IN (' . implode(',', $expages) . ')'; } } $author_query = ''; if (!empty($r['authors'])) { $post_authors = preg_split('/[\\s,]+/', $r['authors']); if (!empty($post_authors)) { foreach ($post_authors as $post_author) { //Do we have an author id or an author login? if (0 == intval($post_author)) { $post_author = get_user_by('login', $post_author); if (empty($post_author)) { continue; } if (empty($post_author->ID)) { continue; } $post_author = $post_author->ID; } if ('' == $author_query) { $author_query = $hqdb->prepare(' post_author = %d ', $post_author); } else { $author_query .= $hqdb->prepare(' OR post_author = %d ', $post_author); } } if ('' != $author_query) { $author_query = " AND ({$author_query})"; } } } $join = ''; $where = "{$exclusions} {$inclusions} "; if ('' !== $meta_key || '' !== $meta_value) { $join = " LEFT JOIN {$hqdb->postmeta} ON ( {$hqdb->posts}.ID = {$hqdb->postmeta}.post_id )"; // meta_key and meta_value might be slashed $meta_key = hq_unslash($meta_key); $meta_value = hq_unslash($meta_value); if ('' !== $meta_key) { $where .= $hqdb->prepare(" AND {$hqdb->postmeta}.meta_key = %s", $meta_key); } if ('' !== $meta_value) { $where .= $hqdb->prepare(" AND {$hqdb->postmeta}.meta_value = %s", $meta_value); } } if (is_array($parent)) { $post_parent__in = implode(',', array_map('absint', (array) $parent)); if (!empty($post_parent__in)) { $where .= " AND post_parent IN ({$post_parent__in})"; } } elseif ($parent >= 0) { $where .= $hqdb->prepare(' AND post_parent = %d ', $parent); } if (1 == count($post_status)) { $where_post_type = $hqdb->prepare("post_type = %s AND post_status = %s", $r['post_type'], reset($post_status)); } else { $post_status = implode("', '", $post_status); $where_post_type = $hqdb->prepare("post_type = %s AND post_status IN ('{$post_status}')", $r['post_type']); } $orderby_array = array(); $allowed_keys = array('author', 'post_author', 'date', 'post_date', 'title', 'post_title', 'name', 'post_name', 'modified', 'post_modified', 'modified_gmt', 'post_modified_gmt', 'menu_order', 'parent', 'post_parent', 'ID', 'rand', 'comment_count'); foreach (explode(',', $r['sort_column']) as $orderby) { $orderby = trim($orderby); if (!in_array($orderby, $allowed_keys)) { continue; } switch ($orderby) { case 'menu_order': break; case 'ID': $orderby = "{$hqdb->posts}.ID"; break; case 'rand': $orderby = 'RAND()'; break; case 'comment_count': $orderby = "{$hqdb->posts}.comment_count"; break; default: if (0 === strpos($orderby, 'post_')) { $orderby = "{$hqdb->posts}." . $orderby; } else { $orderby = "{$hqdb->posts}.post_" . $orderby; } } $orderby_array[] = $orderby; } $sort_column = !empty($orderby_array) ? implode(',', $orderby_array) : "{$hqdb->posts}.post_title"; $sort_order = strtoupper($r['sort_order']); if ('' !== $sort_order && !in_array($sort_order, array('ASC', 'DESC'))) { $sort_order = 'ASC'; } $query = "SELECT * FROM {$hqdb->posts} {$join} WHERE ({$where_post_type}) {$where} "; $query .= $author_query; $query .= " ORDER BY " . $sort_column . " " . $sort_order; if (!empty($number)) { $query .= ' LIMIT ' . $offset . ',' . $number; } $pages = $hqdb->get_results($query); if (empty($pages)) { /** This filter is documented in hq-includes/post.php */ $pages = apply_filters('get_pages', array(), $r); return $pages; } // Sanitize before caching so it'll only get done once. $num_pages = count($pages); for ($i = 0; $i < $num_pages; $i++) { $pages[$i] = sanitize_post($pages[$i], 'raw'); } // Update cache. update_post_cache($pages); if ($child_of || $hierarchical) { $pages = get_page_children($child_of, $pages); } if (!empty($r['exclude_tree'])) { $exclude = hq_parse_id_list($r['exclude_tree']); foreach ($exclude as $id) { $children = get_page_children($id, $pages); foreach ($children as $child) { $exclude[] = $child->ID; } } $num_pages = count($pages); for ($i = 0; $i < $num_pages; $i++) { if (in_array($pages[$i]->ID, $exclude)) { unset($pages[$i]); } } } $page_structure = array(); foreach ($pages as $page) { $page_structure[] = $page->ID; } hq_cache_set($cache_key, $page_structure, 'posts'); // Convert to HQ_Post instances $pages = array_map('get_post', $pages); /** * Filter the retrieved list of pages. * * @since 0.0.1 * * @param array $pages List of pages to retrieve. * @param array $r Array of get_pages() arguments. */ return apply_filters('get_pages', $pages, $r); }
/** * Builds the sitemap and writes it into a xml file. * * @since 3.0 * @access public * @author Arne Brachhold <himself [at] arnebrachhold [dot] de> * @return array An array with messages such as failed writes etc. */ function BuildSitemap() { global $wpdb, $posts, $wp_version; $this->Initate(); if ($this->GetOption("b_memory") != '') { @ini_set("memory_limit", $this->GetOption("b_memory")); } if ($this->GetOption("sm_b_time") != -1) { @set_time_limit($this->GetOption("sm_b_time")); } //This object saves the status information of the script directly to the database $status = new GoogleSitemapGeneratorStatus(); //Other plugins can detect if the building process is active $this->_isActive = true; //$this->AddElement(new GoogleSitemapGeneratorXmlEntry()); //Debug mode? $debug = $this->GetOption("b_debug"); if ($this->GetOption("b_xml")) { $fileName = $this->GetXmlPath(); $status->StartXml($this->GetXmlPath(), $this->GetXmlUrl()); if ($this->IsFileWritable($fileName)) { $this->_fileHandle = fopen($fileName, "w"); if (!$this->_fileHandle) { $status->EndXml(false, "Not openable"); } } else { $status->EndXml(false, "not writable"); } } //Write gzipped sitemap file if ($this->IsGzipEnabled()) { $fileName = $this->GetZipPath(); $status->StartZip($this->GetZipPath(), $this->GetZipUrl()); if ($this->IsFileWritable($fileName)) { $this->_fileZipHandle = gzopen($fileName, "w1"); if (!$this->_fileZipHandle) { $status->EndZip(false, "Not openable"); } } else { $status->EndZip(false, "not writable"); } } if (!$this->_fileHandle && !$this->_fileZipHandle) { $status->End(); return; } //Content of the XML file $this->AddElement(new GoogleSitemapGeneratorXmlEntry('<?xml version="1.0" encoding="UTF-8"' . '?' . '>')); if ($this->GetOption("b_style") != '') { $this->AddElement(new GoogleSitemapGeneratorXmlEntry('<' . '?xml-stylesheet type="text/xsl" href="' . $this->GetOption("b_style") . '"?' . '>')); } $this->AddElement(new GoogleSitemapGeneratorDebugEntry("generator=\"wordpress/" . get_bloginfo('version') . "\"")); $this->AddElement(new GoogleSitemapGeneratorDebugEntry("sitemap-generator-url=\"http://www.arnebrachhold.de\" sitemap-generator-version=\"" . $this->GetVersion() . "\"")); $this->AddElement(new GoogleSitemapGeneratorDebugEntry("generated-on=\"" . date(get_option("date_format") . " " . get_option("time_format")) . "\"")); //All comments as an asso. Array (postID=>commentCount) $comments = $this->GetOption("b_prio_provider") != "" ? $this->GetComments() : array(); //Full number of comments $commentCount = count($comments) > 0 ? $this->GetCommentCount($comments) : 0; if ($debug && $this->GetOption("b_prio_provider") != "") { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Total comment count: " . $commentCount)); } //Go XML! $this->AddElement(new GoogleSitemapGeneratorXmlEntry('<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">')); $home = get_bloginfo('url'); //Add the home page (WITH a slash!) if ($this->GetOption("in_home")) { $this->AddUrl(trailingslashit($home), $this->GetTimestampFromMySql(get_lastpostmodified('GMT')), $this->GetOption("cf_home"), $this->GetOption("pr_home")); } //Add the posts if ($this->GetOption("in_posts") || $this->GetOption("in_pages")) { if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Start Postings")); } //Pre 2.1 compatibility. 2.1 introduced 'future' as post_status so we don't need to check post_date $wpCompat = floatval($wp_version) < 2.1; $sql = "SELECT `ID`, `post_author`, `post_date`, `post_date_gmt`, `post_status`, `post_name`, `post_modified`, `post_modified_gmt`, `post_parent`, `post_type` FROM `" . $wpdb->posts . "` WHERE "; $where = '('; if ($this->GetOption('in_posts')) { //WP < 2.1: posts are post_status = publish //WP >= 2.1: post_type must be 'post', no date check required because future posts are post_status='future' if ($wpCompat) { $where .= "(post_status = 'publish' AND post_date_gmt <= '" . gmdate('Y-m-d H:i:59') . "')"; } else { $where .= " (post_status = 'publish' AND (post_type = 'post' OR post_type = '')) "; } } if ($this->GetOption('in_pages')) { if ($this->GetOption('in_posts')) { $where .= " OR "; } if ($wpCompat) { //WP < 2.1: posts have post_status = published, pages have post_status = static $where .= " post_status='static' "; } else { //WP >= 2.1: posts have post_type = 'post' and pages have post_type = 'page'. Both must be published. $where .= " (post_status = 'publish' AND post_type = 'page') "; } } $where .= ") "; $excludes = $this->GetOption('b_exclude'); if (is_array($excludes) && count($excludes) > 0) { $where .= " AND ID NOT IN ('" . implode("','", $excludes) . "')"; } $where .= " AND post_password='' ORDER BY post_modified DESC"; $sql .= $where; if ($this->GetOption("sm_b_max_posts") > 0) { $sql .= " LIMIT 0," . $this->GetOption("sm_b_max_posts"); } $postCount = intval($wpdb->get_var("SELECT COUNT(*) AS cnt FROM `" . $wpdb->posts . "` WHERE " . $where, 0, 0)); //Create a new connection because we are using mysql_unbuffered_query and don't want to disturb the WP connection //Safe Mode for other plugins which use mysql_query() without a connection handler and will destroy our resultset :( $con = $postRes = null; if ($this->GetOption("b_safemode") === true) { $postRes = mysql_query($sql, $wpdb->dbh); if (!$postRes) { trigger_error("MySQL query failed: " . mysql_error(), E_USER_NOTICE); //E_NOTE will be displayed on our debug mode return; } } else { $con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD, true); if (!$con) { trigger_error("MySQL Connection failed: " . mysql_error(), E_USER_NOTICE); return; } if (!mysql_select_db(DB_NAME, $con)) { trigger_error("MySQL DB Select failed: " . mysql_error(), E_USER_NOTICE); return; } $postRes = mysql_unbuffered_query($sql, $con); if (!$postRes) { trigger_error("MySQL unbuffered query failed: " . mysql_error(), E_USER_NOTICE); return; } } if ($postRes) { //#type $prioProvider GoogleSitemapGeneratorPrioProviderBase $prioProvider = NULL; if ($this->GetOption("b_prio_provider") != '') { $providerClass = $this->GetOption('b_prio_provider'); $prioProvider = new $providerClass($commentCount, $postCount); } //$posts is used by Alex King's Popularity Contest plugin //if($posts == null || !is_array($posts)) { // $posts = &$postRes; //} $z = 1; $zz = 1; //Default priorities $default_prio_posts = $this->GetOption('pr_posts'); $default_prio_pages = $this->GetOption('pr_pages'); //Change frequencies $cf_pages = $this->GetOption('sm_cf_pages'); $cf_posts = $this->GetOption('sm_cf_posts'); $minPrio = $this->GetOption('pr_posts_min'); //Cycle through all posts and add them while ($post = mysql_fetch_object($postRes)) { //Fill the cache with our DB result. Since it's incomplete (no text-content for example), we will clean it later. $cache = array(&$post); update_post_cache($cache); $permalink = get_permalink($post->ID); if ($permalink != $home) { $isPage = false; if ($wpCompat) { $isPage = $post->post_status == 'static'; } else { $isPage = $post->post_type == 'page'; } //Set the current working post $GLOBALS['post'] =& $post; //Default Priority if auto calc is disabled $prio = 0; if ($isPage) { //Priority for static pages $prio = $default_prio_pages; } else { //Priority for normal posts $prio = $default_prio_posts; } //If priority calc. is enabled, calculate (but only for posts, not pages)! if ($prioProvider !== null && !$isPage) { //Comment count for this post $cmtcnt = isset($comments[$post->ID]) ? $comments[$post->ID] : 0; $prio = $prioProvider->GetPostPriority($post->ID, $cmtcnt); if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry('Debug: Priority report of postID ' . $post->ID . ': Comments: ' . $cmtcnt . ' of ' . $commentCount . ' = ' . $prio . ' points')); } } if (!$isPage && $minPrio > 0 && $prio < $minPrio) { $prio = $minPrio; } //Add it $this->AddUrl($permalink, $this->GetTimestampFromMySql($post->post_modified_gmt && $post->post_modified_gmt != '0000-00-00 00:00:00' ? $post->post_modified_gmt : $post->post_date_gmt), $isPage ? $cf_pages : $cf_posts, $prio); } //Update the status every 100 posts and at the end. //If the script breaks because of memory or time limit, //we have a "last reponded" value which can be compared to the server settings if ($zz == 100 || $z == $postCount) { $status->SaveStep($z); $zz = 0; } else { $zz++; } $z++; //Clean cache because it's incomplete clean_post_cache($post->ID); } unset($postRes); unset($prioProvider); if ($this->GetOption("b_safemode") !== true && $con) { mysql_close($con); } } if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: End Postings")); } } //Add the cats if ($this->GetOption("in_cats")) { if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Start Cats")); } if (!$this->IsTaxonomySupported()) { $catsRes = $wpdb->get_results("\r\n\t\t\t\t\t\t\tSELECT \r\n\t\t\t\t\t\t\t\tc.cat_ID AS ID, \r\n\t\t\t\t\t\t\t\tMAX(p.post_modified_gmt) AS last_mod \r\n\t\t\t\t\t\t\tFROM \r\n\t\t\t\t\t\t\t\t`" . $wpdb->categories . "` c,\r\n\t\t\t\t\t\t\t\t`" . $wpdb->post2cat . "` pc,\r\n\t\t\t\t\t\t\t\t`" . $wpdb->posts . "` p\r\n\t\t\t\t\t\t\tWHERE\r\n\t\t\t\t\t\t\t\tpc.category_id = c.cat_ID\r\n\t\t\t\t\t\t\t\tAND p.ID = pc.post_id\r\n\t\t\t\t\t\t\t\tAND p.post_status = 'publish'\r\n\t\t\t\t\t\t\t\tAND p.post_type='post'\r\n\t\t\t\t\t\t\tGROUP\r\n\t\t\t\t\t\t\t\tBY c.cat_id\r\n\t\t\t\t\t\t\t"); if ($catsRes) { foreach ($catsRes as $cat) { if ($cat && $cat->ID && $cat->ID > 0) { if ($debug) { if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Cat-ID:" . $cat->ID)); } } $this->AddUrl(get_category_link($cat->ID), $this->GetTimestampFromMySql($cat->last_mod), $this->GetOption("cf_cats"), $this->GetOption("pr_cats")); } } } } else { $cats = get_terms("category", array("hide_empty" => true, "hierarchical" => false)); if ($cats && is_array($cats) && count($cats) > 0) { foreach ($cats as $cat) { $this->AddUrl(get_category_link($cat->term_id), 0, $this->GetOption("cf_cats"), $this->GetOption("pr_cats")); } } } if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: End Cats")); } } //Add the archives if ($this->GetOption("in_arch")) { if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Start Archive")); } $now = current_time('mysql'); //WP2.1 introduced post_status='future', for earlier WP versions we need to check the post_date_gmt $arcresults = $wpdb->get_results("\r\n\t\t\t\t\t\tSELECT DISTINCT \r\n\t\t\t\t\t\t\tYEAR(post_date_gmt) AS `year`, \r\n\t\t\t\t\t\t\tMONTH(post_date_gmt) AS `month`, \r\n\t\t\t\t\t\t\tMAX(post_date_gmt) as last_mod, \r\n\t\t\t\t\t\t\tcount(ID) as posts \r\n\t\t\t\t\t\tFROM \r\n\t\t\t\t\t\t\t{$wpdb->posts} \r\n\t\t\t\t\t\tWHERE \r\n\t\t\t\t\t\t\tpost_date < '{$now}' \r\n\t\t\t\t\t\t\tAND post_status = 'publish' \r\n\t\t\t\t\t\t\tAND post_type = 'post'\r\n\t\t\t\t\t\t\t" . (floatval($wp_version) < 2.1 ? "AND {$wpdb->posts}.post_date_gmt <= '" . gmdate('Y-m-d H:i:59') . "'" : "") . "\r\n\t\t\t\t\t\tGROUP BY \r\n\t\t\t\t\t\t\tYEAR(post_date_gmt), \r\n\t\t\t\t\t\t\tMONTH(post_date_gmt) \r\n\t\t\t\t\t\tORDER BY \r\n\t\t\t\t\t\t\tpost_date_gmt DESC"); if ($arcresults) { foreach ($arcresults as $arcresult) { $url = get_month_link($arcresult->year, $arcresult->month); $changeFreq = ""; //Archive is the current one if ($arcresult->month == date("n") && $arcresult->year == date("Y")) { $changeFreq = $this->GetOption("cf_arch_curr"); } else { // Archive is older $changeFreq = $this->GetOption("cf_arch_old"); } $this->AddUrl($url, $this->GetTimestampFromMySql($arcresult->last_mod), $changeFreq, $this->GetOption("pr_arch")); } } if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: End Archive")); } } //Add the author pages if ($this->GetOption("in_auth")) { if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Start Author pages")); } $linkFunc = null; //get_author_link is deprecated in WP 2.1, try to use get_author_posts_url first. if (function_exists('get_author_posts_url')) { $linkFunc = 'get_author_posts_url'; } else { if (function_exists('get_author_link')) { $linkFunc = 'get_author_link'; } } //Who knows what happens in later WP versions, so check again if it worked if ($linkFunc !== null) { //Unfortunately there is no API function to get all authors, so we have to do it the dirty way... //We retrieve only users with published and not password protected posts (and not pages) //WP2.1 introduced post_status='future', for earlier WP versions we need to check the post_date_gmt $sql = "SELECT DISTINCT \r\n\t\t\t\t\t\t\t{$wpdb->users}.ID, \r\n\t\t\t\t\t\t\t{$wpdb->users}.user_nicename, \r\n\t\t\t\t\t\t\tMAX({$wpdb->posts}.post_modified_gmt) AS last_post \r\n\t\t\t\t\t\tFROM \r\n\t\t\t\t\t\t\t{$wpdb->users}, \r\n\t\t\t\t\t\t\t{$wpdb->posts} \r\n\t\t\t\t\t\tWHERE \r\n\t\t\t\t\t\t\t{$wpdb->posts}.post_author = {$wpdb->posts}.ID \r\n\t\t\t\t\t\t\tAND {$wpdb->posts}.post_status = 'publish'\r\n\t\t\t\t\t\t\tAND {$wpdb->posts}.post_type = 'post' \r\n\t\t\t\t\t\t\tAND {$wpdb->posts}.post_password = '' \r\n\t\t\t\t\t\t\t" . (floatval($wp_version) < 2.1 ? "AND {$wpdb->posts}.post_date_gmt <= '" . gmdate('Y-m-d H:i:59') . "'" : "") . "\r\n\t\t\t\t\t\tGROUP BY \r\n\t\t\t\t\t\t\t{$wpdb->posts}.ID, \r\n\t\t\t\t\t\t\t{$wpdb->users}.user_nicename"; $authors = $wpdb->get_results($sql); if ($authors && is_array($authors)) { foreach ($authors as $author) { if ($debug) { if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Author-ID:" . $author->ID)); } } $url = $linkFunc == 'get_author_posts_url' ? get_author_posts_url($author->ID, $author->user_nicename) : get_author_link(false, $author->ID, $author->user_nicename); $this->AddUrl($url, $this->GetTimestampFromMySql($author->last_post), $this->GetOption("cf_auth"), $this->GetOption("pr_auth")); } } } else { //Too bad, no author pages for you :( if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: No valid author link function found")); } } if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: End Author pages")); } } //Add tag pages if ($this->GetOption("in_tags") && $this->IsTaxonomySupported()) { if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Start Tags")); } $tags = get_terms("post_tag", array("hide_empty" => true, "hierarchical" => false)); if ($tags && is_array($tags) && count($tags) > 0) { foreach ($tags as $tag) { $this->AddUrl(get_tag_link($tag->term_id), 0, $this->GetOption("cf_tags"), $this->GetOption("pr_tags")); } } if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: End Tags")); } } //Add the custom pages if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Start Custom Pages")); } if ($this->_pages && is_array($this->_pages) && count($this->_pages) > 0) { //#type $page GoogleSitemapGeneratorPage foreach ($this->_pages as $page) { $this->AddUrl($page->GetUrl(), $page->getLastMod(), $page->getChangeFreq(), $page->getPriority()); } } if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: End Custom Pages")); } if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: Start additional URLs")); } do_action("sm_buildmap"); if ($debug) { $this->AddElement(new GoogleSitemapGeneratorDebugEntry("Debug: End additional URLs")); } $this->AddElement(new GoogleSitemapGeneratorXmlEntry("</urlset>")); $pingUrl = ''; if ($this->GetOption("b_xml")) { if ($this->_fileHandle && fclose($this->_fileHandle)) { $this->_fileHandle = null; $status->EndXml(true); $pingUrl = $this->GetXmlUrl(); } else { $status->EndXml(false, "Could not close the sitemap file."); } } if ($this->IsGzipEnabled()) { if ($this->_fileZipHandle && fclose($this->_fileZipHandle)) { $this->_fileZipHandle = null; $status->EndZip(true); $pingUrl = $this->GetZipUrl(); } else { $status->EndZip(false, "Could not close the zipped sitemap file"); } } //Ping Google if ($this->GetOption("b_ping") && !empty($pingUrl)) { $sPingUrl = "http://www.google.com/webmasters/sitemaps/ping?sitemap=" . urlencode($pingUrl); $status->StartGooglePing($sPingUrl); $pingres = $this->RemoteOpen($sPingUrl); if ($pingres == NULL || $pingres === false) { $status->EndGooglePing(false, $this->_lastError); } else { $status->EndGooglePing(true); } } //Ping Ask.com if ($this->GetOption("b_pingask") && !empty($pingUrl)) { $sPingUrl = "http://submissions.ask.com/ping?sitemap=" . urlencode($pingUrl); $status->StartAskPing($sPingUrl); $pingres = $this->RemoteOpen($sPingUrl); if ($pingres == NULL || $pingres === false || strpos($pingres, "successfully received and added") === false) { //Ask.com returns 200 OK even if there was an error, so we need to check the content. $status->EndAskPing(false, $this->_lastError); } else { $status->EndAskPing(true); } } //Ping YAHOO if ($this->GetOption("sm_b_pingyahoo") === true && $this->GetOption("sm_b_yahookey") != "" && !empty($pingUrl)) { $sPingUrl = "http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=" . $this->GetOption("sm_b_yahookey") . "&url=" . urlencode($pingUrl); $status->StartYahooPing($sPingUrl); $pingres = $this->RemoteOpen($sPingUrl); if ($pingres == NULL || $pingres === false || strpos(strtolower($pingres), "success") === false) { $status->EndYahooPing(false, $this->_lastError); } else { $status->EndYahooPing(true); } } //Ping MSN if ($this->GetOption("b_pingmsn") && !empty($pingUrl)) { $sPingUrl = "http://webmaster.live.com/ping.aspx?siteMap=" . urlencode($pingUrl); $status->StartMsnPing($sPingUrl); $pingres = $this->RemoteOpen($sPingUrl); if ($pingres == NULL || $pingres === false || strpos($pingres, "Thanks for submitting your sitemap") === false) { $status->EndMsnPing(false, $this->_lastError); } else { $status->EndMsnPing(true); } } $status->End(); $this->_isActive = false; //done... return $status; }
public static function flt_get_pages($results, $args = array()) { $results = (array) $results; global $wpdb; // === BEGIN PP ADDITION: global var; various special case exemption checks === // global $pp, $current_user; // buffer titles in case they were filtered previously $titles = pp_get_property_array($results, 'ID', 'post_title'); // depth is not really a get_pages arg, but remap exclude arg to exclude_tree if wp_list_terms called with depth=1 if (!empty($args['exclude']) && empty($args['exclude_tree']) && !empty($args['depth']) && 1 == $args['depth']) { if (0 !== strpos($args['exclude'], ',')) { // work around wp_list_pages() bug of attaching leading comma if a plugin uses wp_list_pages_excludes filter $args['exclude_tree'] = $args['exclude']; } } // // === END PP ADDITION === // ================================= $defaults = array('child_of' => 0, 'sort_order' => 'ASC', 'sort_column' => 'post_title', 'hierarchical' => 1, 'exclude' => array(), 'include' => array(), 'meta_key' => '', 'meta_value' => '', 'authors' => '', 'parent' => -1, 'exclude_tree' => '', 'number' => '', 'offset' => 0, 'post_type' => 'page', 'post_status' => 'publish', 'depth' => 0, 'suppress_filters' => 0, 'required_operation' => '', 'alternate_operation' => ''); // PP arguments added above // === BEGIN PP ADDITION: support front-end optimization $post_type = isset($args['post_type']) ? $args['post_type'] : $defaults['post_type']; $enabled_post_types = pp_get_enabled_post_types(); if (defined('PP_UNFILTERED_FRONT')) { if (defined('PP_UNFILTERED_FRONT_TYPES')) { $unfiltered_types = str_replace(' ', '', PP_UNFILTERED_FRONT_TYPES); $unfiltered_types = explode(',', constant($unfiltered_types)); $enabled_post_types = array_diff($enabled_post_types, $unfiltered_types); } else { return $results; } } if (!in_array($post_type, $enabled_post_types)) { return $results; } if (pp_is_front()) { if ('page' == $post_type && defined('PP_GET_PAGES_LEAN')) { // custom types are likely to have custom fields $defaults['fields'] = "{$wpdb->posts}.ID, {$wpdb->posts}.post_title, {$wpdb->posts}.post_parent, {$wpdb->posts}.post_date, {$wpdb->posts}.post_date_gmt, {$wpdb->posts}.post_status, {$wpdb->posts}.post_name, {$wpdb->posts}.post_modified, {$wpdb->posts}.post_modified_gmt, {$wpdb->posts}.guid, {$wpdb->posts}.menu_order, {$wpdb->posts}.comment_count"; } else { $defaults['fields'] = "{$wpdb->posts}.*"; } } else { // required for xmlrpc getpagelist method $defaults['fields'] = "{$wpdb->posts}.*"; } // === END PP MODIFICATION === $r = wp_parse_args($args, $defaults); $args['number'] = (int) $r['number']; $args['offset'] = absint($r['offset']); $args['child_of'] = (int) $r['child_of']; extract(apply_filters('pp_get_pages_args', $r), EXTR_SKIP); // PPE filter modifies append_page, exclude_tree // workaround for CMS Tree Page View (passes post_parent instead of parent) if (-1 == $parent && isset($args['post_parent'])) { $args['parent'] = $args['post_parent']; $parent = $args['post_parent']; } // Make sure the post type is hierarchical $hierarchical_post_types = get_post_types(array('public' => true, 'hierarchical' => true)); if (!in_array($post_type, $hierarchical_post_types)) { return $results; } // Make sure we have a valid post status if (is_admin() && 'any' === $post_status) { $post_status = ''; } if ($post_status) { if (!is_array($post_status) && strpos($post_status, ',')) { $post_status = explode(',', $post_status); } if (array_diff((array) $post_status, get_post_stati())) { return $results; } } $intercepted_pages = apply_filters('pp_get_pages_intercept', false, $results, $args); if (is_array($intercepted_pages)) { return $intercepted_pages; } //$pp->last_get_pages_args = $r; // don't copy entire args array unless it proves necessary $pp->last_get_pages_depth = $depth; $pp->last_get_pages_suppress_filters = $suppress_filters; if ($suppress_filters) { return $results; } $orderby_array = array(); $allowed_keys = array('author', 'post_author', 'date', 'post_date', 'title', 'post_title', 'name', 'post_name', 'modified', 'post_modified', 'modified_gmt', 'post_modified_gmt', 'menu_order', 'parent', 'post_parent', 'ID', 'rand', 'comment_count'); foreach (explode(',', $sort_column) as $orderby) { $orderby = trim($orderby); if (!in_array($orderby, $allowed_keys)) { continue; } switch ($orderby) { case 'menu_order': break; case 'ID': $orderby = "{$wpdb->posts}.ID"; break; case 'rand': $orderby = 'RAND()'; break; case 'comment_count': $orderby = "{$wpdb->posts}.comment_count"; break; default: if (0 === strpos($orderby, 'post_')) { $orderby = "{$wpdb->posts}." . $orderby; } else { $orderby = "{$wpdb->posts}.post_" . $orderby; } } $orderby_array[] = $orderby; } $sort_column = !empty($orderby_array) ? implode(',', $orderby_array) : "{$wpdb->posts}.post_title"; // $args can be whatever, only use the args defined in defaults to compute the key $key = md5(serialize(compact(array_keys($defaults)))); $last_changed = wp_cache_get('last_changed', 'posts'); if (!$last_changed) { $last_changed = microtime(); wp_cache_set('last_changed', $last_changed, 'posts'); } $cache_key = "pp_get_pages:{$key}:{$last_changed}"; if ($cache = wp_cache_get($cache_key, 'posts')) { // Convert to WP_Post instances $pages = array_map('get_post', $cache); $pages = apply_filters('pp_get_pages', $pages, $r); return $pages; } $inclusions = ''; if (!empty($include)) { $child_of = 0; //ignore child_of, parent, exclude, meta_key, and meta_value params if using include $parent = -1; $exclude = ''; $meta_key = ''; $meta_value = ''; $hierarchical = false; $incpages = wp_parse_id_list($include); if (!empty($incpages)) { foreach ($incpages as $incpage) { if (empty($inclusions)) { $inclusions = ' AND ( ID = ' . intval($incpage) . ' '; } else { $inclusions .= ' OR ID = ' . intval($incpage) . ' '; } } } } if (!empty($inclusions)) { $inclusions .= ')'; } $exclusions = ''; if (!empty($exclude)) { $expages = wp_parse_id_list($exclude); if (!empty($expages)) { foreach ($expages as $expage) { if (empty($exclusions)) { $exclusions = ' AND ( ID <> ' . intval($expage) . ' '; } else { $exclusions .= ' AND ID <> ' . intval($expage) . ' '; } } } } if (!empty($exclusions)) { $exclusions .= ')'; } $author_query = ''; if (!empty($authors)) { $post_authors = wp_parse_id_list($authors); if (!empty($post_authors)) { foreach ($post_authors as $post_author) { //Do we have an author id or an author login? if (0 == intval($post_author)) { $post_author = get_user_by('login', $post_author); if (empty($post_author)) { continue; } if (empty($post_author->ID)) { continue; } $post_author = $post_author->ID; } if ('' == $author_query) { $author_query = ' post_author = ' . intval($post_author) . ' '; } else { $author_query .= ' OR post_author = ' . intval($post_author) . ' '; } } if ('' != $author_query) { $author_query = " AND ({$author_query})"; } } } $join = ''; $where = "{$exclusions} {$inclusions} "; if (!empty($meta_key) || !empty($meta_value)) { $join = " INNER JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id"; // PP MODIFICATION: was LEFT JOIN in WP 3.0 core // meta_key and meta_value might be slashed $meta_key = stripslashes($meta_key); $meta_value = stripslashes($meta_value); if (!empty($meta_key)) { $where .= $wpdb->prepare(" AND {$wpdb->postmeta}.meta_key = %s", $meta_key); } if (!empty($meta_value)) { $where .= $wpdb->prepare(" AND {$wpdb->postmeta}.meta_value = %s", $meta_value); } } if ($parent >= 0) { $where .= $wpdb->prepare(' AND ' . apply_filters('pp_get_pages_parent', 'post_parent = %d ', $args), $parent); } // === BEGIN PP MODIFICATION: // allow pages of multiple statuses to be displayed (requires default status=publish to be ignored) // $where_post_type = $wpdb->prepare("post_type = %s", $post_type); $where_status = ''; global $current_user; $is_front = pp_is_front(); if ($is_front && !empty($current_user->ID)) { $frontend_list_private = !defined('PP_SUPPRESS_PRIVATE_PAGES'); } else { $frontend_list_private = false; } $force_publish_status = !$frontend_list_private && 'publish' == $post_status; if ($is_front) { // since we will be applying status clauses based on content-specific roles, only a sanity check safeguard is needed when post_status is unspecified or defaulted to "publish" $safeguard_statuses = array(); foreach (pp_get_post_stati(array('internal' => false, 'post_type' => $post_type), 'object') as $status_name => $status_obj) { if (!$is_front || $status_obj->private || $status_obj->public) { $safeguard_statuses[] = $status_name; } } } // WP core does not include private pages in query. Include private statuses in anticipation of user-specific filtering if (is_array($post_status)) { $where_status = "AND post_status IN ('" . implode("','", $post_status) . "')"; } elseif ($post_status && ('publish' != $post_status || $is_front && !$frontend_list_private)) { $where_status = $wpdb->prepare("AND post_status = %s", $post_status); } elseif ($is_front) { $where_status = "AND post_status IN ('" . implode("','", $safeguard_statuses) . "')"; } else { $where_status = "AND post_status NOT IN ('" . implode("','", get_post_stati(array('internal' => true))) . "')"; } $where_id = ''; global $pagenow; if (is_admin() && in_array($pagenow, array('post.php', 'post-new.php'))) { global $post; if ($post) { $where_id = "AND ID != {$post->ID}"; } } $where = "AND {$where_post_type} AND ( 1=1 {$where_status} {$where} {$author_query} {$where_id} )"; $orderby = "ORDER BY {$sort_column} {$sort_order}"; $limits = !empty($number) ? ' LIMIT ' . $offset . ',' . $number : ''; $query = "SELECT {$fields} FROM {$wpdb->posts} {$join} WHERE 1=1 {$where} {$orderby} {$limits}"; if (pp_is_front() && apply_filters('pp_teaser_enabled', false, 'post', $post_type) && !defined('PP_TEASER_HIDE_PAGE_LISTING')) { // We are in the front end and the teaser is enabled for pages // TODO: move to PPTX $query = str_replace("post_status = 'publish'", " post_status IN ('" . implode("','", $safeguard_statuses) . "')", $query); $pages = $wpdb->get_results($query); // execute unfiltered query // Pass results of unfiltered query through the teaser filter. // If listing private pages is disabled, they will be omitted completely, but restricted published pages // will still be teased. This is a slight design compromise to satisfy potentially conflicting user goals without yet another option $pages = apply_filters('pp_posts_teaser', $pages, $post_type, array('request' => $query, 'force_teaser' => true)); $tease_all = true; } else { $_args = array('skip_teaser' => true, 'retain_status' => $force_publish_status); $groupby = $distinct = ''; global $pagenow; if (in_array($pagenow, array('post.php', 'post-new.php'))) { $clauses = apply_filters('pp_get_pages_clauses', compact('distinct', 'fields', 'join', 'where', 'groupby', 'orderby', 'limits'), $post_type, $args); } else { // Pass query through the request filter $_args['post_types'] = $post_type; if ($required_operation) { $_args['required_operation'] = $required_operation; } else { $_args['required_operation'] = pp_is_front() && !is_preview() ? 'read' : 'edit'; } if ('edit' == $_args['required_operation'] && isset($args['post_parent']) || 'associate' == $alternate_operation) { // workaround for CMS Page View $_args['alternate_required_ops'] = array('associate'); } $clauses = apply_filters('pp_posts_clauses', compact('distinct', 'fields', 'join', 'where', 'groupby', 'orderby', 'limits'), $_args); } // Execute the filtered query $pages = $wpdb->get_results("SELECT {$distinct} {$clauses['fields']} FROM {$wpdb->posts} {$clauses['join']} WHERE 1=1 {$clauses['where']} {$clauses['orderby']} {$clauses['limits']}"); } if (empty($pages)) { // alternate hook name (WP core already applied get_pages filter) return apply_filters('pp_get_pages', array(), $r); } if ($child_of) { $pages = get_page_children($child_of, $pages); } // restore buffered titles in case they were filtered previously pp_restore_property_array($pages, $titles, 'ID', 'post_title'); // // === END PP MODIFICATION === // ==================================== $num_pages = count($pages); for ($i = 0; $i < $num_pages; $i++) { $pages[$i] = sanitize_post($pages[$i], 'raw'); } // Press Permit note: WP core get_pages has already updated wp_cache and pagecache with unfiltered results. update_post_cache($pages); // === BEGIN PP MODIFICATION: Support a disjointed pages tree with some parents hidden ======== if ($child_of || empty($tease_all)) { // if we're including all pages with teaser, no need to continue thru tree remapping $ancestors = PP_Ancestry::get_page_ancestors(); // array of all ancestor IDs for keyed page_id, with direct parent first $orderby = $sort_column; $remap_args = compact('child_of', 'parent', 'exclude', 'depth', 'orderby'); // one or more of these args may have been modified after extraction PP_Ancestry::remap_tree($pages, $ancestors, $remap_args); } // === END PP MODIFICATION === // ==================================== if (!empty($exclude_tree)) { $exclude = array(); $exclude = (int) $exclude_tree; $children = get_page_children($exclude, $pages); // PP note: okay to use unfiltered WP function here since it's only used for excluding $excludes = array(); foreach ($children as $child) { $excludes[] = $child->ID; } $excludes[] = $exclude; $total = count($pages); for ($i = 0; $i < $total; $i++) { if (isset($pages[$i]) && in_array($pages[$i]->ID, $excludes)) { unset($pages[$i]); } } } if (!empty($append_page) && !empty($pages)) { $found = false; foreach (array_keys($pages) as $key) { if ($append_page->ID == $pages[$key]->ID) { $found = true; break; } } if (empty($found)) { $pages[] = $append_page; } } // re-index the array, just in case anyone cares $pages = array_values($pages); $page_structure = array(); foreach ($pages as $page) { $page_structure[] = $page->ID; } wp_cache_set($cache_key, $page_structure, 'posts'); // Convert to WP_Post instances $pages = array_map('get_post', $pages); // alternate hook name (WP core already applied get_pages filter) return apply_filters('pp_get_pages', $pages, $r); }