Пример #1
0
/**
 * 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);
    }
}
Пример #2
0
/**
 * 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);
}
Пример #3
0
 /**
  * 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 . '&amp;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);
     }
 }
Пример #5
0
/**
 * 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);
    }
}
Пример #6
0
/**
 * 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);
}
Пример #7
0
 /**
  * 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
     }
 }
Пример #8
0
 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'));
 }
Пример #9
0
 /**
  * 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 . '&amp;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);
     }
 }
Пример #11
0
 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;
 }
Пример #12
0
 /**
  * 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;
 }
Пример #14
0
/**
 * 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);
}
Пример #15
0
 /**
  * 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;
 }
Пример #16
0
 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);
 }