'the_content', 'excerpt' => 'the_excerpt', 'comment' => 'comment_text'); var $movedfilters = array(); var $formattedval = array('content' => '', 'excerpt' => '', 'comment' => ''); var $doingexcerpt = false; var $batchmode = true; // save all queries for execution during shutdown hook var $updateQueries = array(); // array of arrays('query', 'filter', 'id') function PreFormatted() { /* filters & actions for preformatting post content 'content_save_pre' and 'phone_content' are used to grab the post content, 'publish_post' and 'edit_post' provide the post number and trigger the save */ add_filter('content_save_pre', array(&$this, 'grabContent'), 99); add_filter('phone_content', array(&$this, 'grabContent'), 99); add_action('publish_post', array(&$this, 'saveContent'), 99); add_action('edit_post', array(&$this, 'saveContent'), 99); /* filters & actions for preformatting post excerpt 'excerpt_save_pre' _should_ be used to grab the post content, but this skips some processing that WP does on the fly, so the excerpt is simply cleared here 'publish_post' and 'edit_post' provide the post number and trigger the save */ //add_filter('excerpt_save_pre', array(&$this, 'grabExcerpt'), 99); add_action('publish_post', array(&$this, 'saveExcerpt'), 99); add_action('edit_post', array(&$this, 'saveExcerpt'), 99); /* filters & actions for preformatting comment content 'comment_save_pre' and 'pre_comment_content' are used to grab the comment content, 'comment_post' and 'edit_comment' provide the comment number and trigger the save */ add_filter('comment_save_pre', array(&$this, 'grabComment'), 99); add_filter('pre_comment_content', array(&$this, 'grabComment'), 99); add_action('comment_post', array(&$this, 'saveComment'), 99); add_action('edit_comment', array(&$this, 'saveComment'), 99); /* these filters trap the post or comment display, which triggers the preformatting magic */ /* ideally 'the_content' filter would be used, but this filter is sadly crippled by WP's paging functions so we have to swap in the preformatted content for the actual content when the posts are queried */ //add_filter('the_content', array(&$this, 'renderContent'), 0); add_filter('the_posts', array(&$this, 'replacePostContent'), 1); add_filter('the_excerpt', array(&$this, 'renderExcerpt'), 0); add_filter('comment_text', array(&$this, 'renderComment'), 0); /* these filters are necessary for excerpt generation the default WP filters try to process the filter 'the_content' when creating an excerpt so the moved filter stream has to be made available in this case. A filter is also added to 'the_content' in rearrangeFilters() */ add_filter('get_the_excerpt', array(&$this, 'startExcerptRedirect'), 1); add_filter('get_the_excerpt', array(&$this, 'endExcerptRedirect'), 99); // this will get moved to the appropriate PreFormatted filter stream add_filter('the_content', array(&$this, 'fixWpTags'), 15); /* once all plugins have been loaded it should be safe to divert the filter streams any plugins that add filters dynamically may still get missed, however */ add_action('plugins_loaded', array(&$this, 'rearrangeFilters'), 99); /* to speed things up a bit more, do updates only after the page is displayed */ if ($this->batchmode) add_action('shutdown', array(&$this, 'executeQueries'), 99); /* upgrade database if necessary */ if (get_option('preformatted_version') < $this->version) $this->upgradeDatabase(); /* for testing purposes - remove for final version */ if (isset($_REQUEST['preformattedclearall'])) $this->clearAll(); } function upgradeDatabase() { global $wpdb; if (get_option('preformatted_version') < '1.9') { // basic upgrade $wpdb->query("ALTER TABLE $wpdb->posts ADD COLUMN post_excerpt_filtered text NOT NULL"); $wpdb->query("ALTER TABLE $wpdb->comments ADD COLUMN comment_content_filtered text NOT NULL"); add_option('preformatted_version', $this->version, "PreFormatted Plugin Version", 'yes'); } // version upgrade only update_option('preformatted_version', $this->version); } function clearAll() { global $wpdb; $wpdb->query("UPDATE $wpdb->posts SET post_content_filtered = '', post_excerpt_filtered = ''"); $wpdb->query("UPDATE $wpdb->comments SET comment_content_filtered = ''"); } function rearrangeFilters() { foreach($this->formatfilters as $filter) $this->moveFilters($filter, $this->filterprefix . $filter); /* used for excerpt generation or post previews in the editing screen */ add_filter('the_content', array(&$this, 'doContentRedirect'), 10); } function showFilters($tag) { // used for debugging only global $wp_filter; $output = "

Filters for $tag:

\n"; return $output; } function moveFilters($oldtag, $newtag) { global $wp_filter; if (!isset($this->movedfilters[$oldtag])) { // move all non-zero priority filters if (isset($wp_filter[$oldtag]) && is_array($wp_filter[$oldtag])) { foreach($wp_filter[$oldtag] as $priority => $filters) { if ($priority > 0) { $wp_filter[$newtag]["$priority"] = $wp_filter[$oldtag]["$priority"]; unset($GLOBALS['wp_filter'][$oldtag]["$priority"]); } } } $this->movedfilters[$oldtag] = $newtag; } } function grabContent(&$content) { $this->applyFormatting('content', stripslashes($content)); return $content; // return original } function grabExcerpt(&$excerpt) { $this->applyFormatting('excerpt', stripslashes($excerpt)); return $excerpt; // return original } function grabComment(&$comment) { $this->applyFormatting('comment', stripslashes($comment)); return $comment; // return original } function applyFormatting($type, &$content) { // generate formatted content $output = apply_filters($this->filterprefix . $this->formatfilters[$type], $content); $this->formattedval[$type] = addslashes($output); return $output; } function saveContent($postid) { $this->saveFormattedValue('content', $postid); } function saveExcerpt($postid) { $this->saveFormattedValue('excerpt', $postid); } function saveComment($commentid) { $this->saveFormattedValue('comment', $commentid); } function saveFormattedValue($type, $id) { global $wpdb; // create update query switch ($type) { case 'content': $query = "UPDATE $wpdb->posts SET post_content_filtered = '{$this->formattedval['content']}' WHERE ID = '$id'"; break; case 'excerpt': $query = "UPDATE $wpdb->posts SET post_excerpt_filtered = '{$this->formattedval['excerpt']}' WHERE ID = '$id'"; break; case 'comment': $query = "UPDATE $wpdb->comments SET comment_content_filtered = '{$this->formattedval['comment']}' WHERE comment_ID = '$id'"; break; } // set updated filter $filter = $this->filterprefix . $type . '_updated'; // save queries for execution later or run now, depending on mode if ($this->batchmode) { $this->updateQueries[] = array('query' => $query, 'filter' => $filter, 'id' => $id); } else { $wpdb->query($query); do_action($filter, $id); } } function executeQueries() { global $wpdb; foreach ($this->updateQueries as $update) { $wpdb->query($update['query']); do_action($update['filter'], $update['id']); } } function getFormattedValue($type, $id, &$original, &$formatted) { // apply user filters $formatted = apply_filters($this->filterprefix . $type . '_filtered', $formatted); // check for preformatted content if (empty($formatted)) { // generate formatted content $formatted = $this->applyFormatting($type, $original); $this->saveFormattedValue($type, $id); } return $formatted; } function replacePostContent(&$posts) { if ($posts) { foreach($posts as $key=>$post) { if (isset($post->post_content_filtered)) $posts[$key]->post_content = $this->getFormattedValue('content', $post->ID, $post->post_content, $posts[$key]->post_content_filtered); } } return $posts; } function renderContent(&$text) { // unused due to paging issue, replacePostContent is used instead global $post; if (!isset($post->post_content_filtered) || ($post->post_content_filtered === false)) return $text; // abort if we are somehow missing this database field else return $this->getFormattedValue('content', $post->ID, $text, $post->post_content_filtered); } function renderExcerpt(&$text) { global $post; if (!isset($post->post_excerpt_filtered) || ($post->post_excerpt_filtered === false)) return $text; // abort if we are somehow missing this database field else return $this->getFormattedValue('excerpt', $post->ID, $text, $post->post_excerpt_filtered); } function renderComment(&$text) { global $comment; if (!isset($comment->comment_content_filtered) || ($comment->comment_content_filtered === false)) return $text; // abort if we are somehow missing this database field else return $this->getFormattedValue('comment', $comment->comment_ID, $text, $comment->comment_content_filtered); } function startExcerptRedirect(&$text) { global $post; // if we have a preformatted excerpt then return it and skip the filter redirect for 'the_content' if (isset($post) && isset($post->post_excerpt_filtered) && !empty($post->post_excerpt_filtered)) $text = $post->post_excerpt_filtered; else $this->doingexcerpt = true; // flag to redirect 'the_content' filter return $text; } function endExcerptRedirect(&$text) { $this->doingexcerpt = false; return $text; // return original } function doContentRedirect(&$text) { if ($this->doingexcerpt) { // if we have preformatted content then return it and skip the filter redirect for 'the_content' global $post; if (isset($post) && isset($post->post_content_filtered) && !empty($post->post_content_filtered)) return $post->post_content_filtered; else // otherwise process content via post content filters (will this ever happen?) return apply_filters($this->filterprefix . $this->formatfilters['content'], $text); } elseif (strstr($_SERVER['PHP_SELF'], 'wp-admin/post.php')) { // in the editing page the formatted data has to be pulled from $postdata (if it exists) global $postdata; if (isset($postdata) && isset($postdata->post_content_filtered) && !empty($postdata->post_content_filtered)) return $postdata->post_content_filtered; else // otherwise process content via post content filters (will this ever happen?) return apply_filters($this->filterprefix . $this->formatfilters['content'], $text); } else return $text; } function fixWpTags($text) { /* quick fix for a common WP problem made worse by this plugin we attempt to move and tags outside of their own

blocks can't do much with ones embedded in other paragraphs without breaking more stuff */ $wptags = array('more', 'nextpage', 'noteaser'); //are there more? foreach($wptags as $tag) $text = preg_replace('%

\s*()\s*

%', '$1', $text); return($text); } } $preformatted_instance = new PreFormatted(); // where it all begins ?>