Skip to content

Instantly share code, notes, and snippets.

@swalkinshaw
Created January 4, 2015 21:33
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save swalkinshaw/e2b87d3378d70bf419d3 to your computer and use it in GitHub Desktop.
Save swalkinshaw/e2b87d3378d70bf419d3 to your computer and use it in GitHub Desktop.
<?php
namespace Roots\Bedrock;
use League\CommonMark\CommonMarkConverter;
class MarkdownPosts {
const POST_OPTION = 'roots/bedrock/markdown_posts';
const IS_MD_META = 'roots/bedrock/is_markdown';
private static $instance;
private $converter;
private $monitoring = ['post' => [], 'parent' => []];
public function __construct() {
$this->converter = new CommonMarkConverter();
}
public static function getInstance() {
if (!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
public function init() {
add_action('admin_init', [$this, 'registerSetting']);
add_filter('wp_insert_post_data', [$this, 'insertPostData'], 10, 2);
add_action('wp_insert_post', [$this, 'insertPost']);
add_filter('edit_post_content', [$this, 'editPostContent'], 10, 2);
add_filter('edit_post_content_filtered', [$this, 'editPostContentFiltered'], 10, 2);
}
private function convertMarkdownToHTML($text) {
return $this->converter->convertToHtml($text);
}
public function editPostContent($content, $id) {
if (!$this->isMarkdown($id)) { return $content; }
$post = get_post($id);
if ($post && !empty($post->post_content_filtered)) {
$post = $this->swapContent($post);
return $post->post_content;
}
return $content;
}
public function editPostContentFiltered($content, $id) {
if (!$this->isPostMarkdownEnabled() && $this->isMarkdown($id)) {
$post = get_post($id);
if ($post && !empty($post->post_content_filtered)) {
$content = '';
}
}
return $content;
}
public function insertPost($post_id) {
$post_parent = get_post_field('post_parent', $post_id);
if (isset( $this->monitoring['content']) && $this->monitoring['content'] === get_post_field('post_content', $post_id)) {
unset($this->monitoring['content']);
$this->setAsMarkdown($post_id);
}
if (isset($this->monitoring['post'][$post_id])) {
unset($this->monitoring['post'][$post_id]);
$this->setAsMarkdown($post_id);
} elseif (isset($this->monitoring['parent'][$post_parent])) {
unset($this->monitoring['parent'][$post_parent]);
$this->setAsMarkdown($post_id);
}
}
public function insertPostData($post_data, $post) {
$post_id = isset($post['ID']) ? $post['ID'] : false;
// bail early if markdown is disabled or this post type is unsupported.
if (!$this->isPostMarkdownEnabled()) {
if ($this->isMarkdown($post_id) && !empty($post_data['post_content_filtered'])) {
$post_data['post_content_filtered'] = '';
}
return $post_data;
}
if (!$this->isPostRevision($post)) {
$post_data['post_content'] = $this->convertMarkdownToHTML($post_data['post_content']);
$post_data['post_content'] = apply_filters('content_save_pre', $post_data['post_content']);
} elseif (strpos($post_data['post_name'], $post_data['post_parent'] . '-autosave') === 0) {
$post_data['post_content'] = $this->convertMarkdownToHTML($post_data['post_content']);
$post_data['post_content'] = apply_filters('content_save_pre', $post_data['post_content']);
}
if ($post_id) {
$this->monitoring['post'][$post_id] = true;
} else {
$this->monitoring['content'] = wp_unslash($post_data['post_content']);
}
if ($this->isPostRevision($post) && $this->isMarkdown($post['post_parent'])) {
$this->monitoring['parent'][$post['post_parent']] = true;
}
return $post_data;
}
private function isMarkdown($post_id) {
return get_metadata('post', $post_id, self::IS_MD_META, true);
}
public function isPostMarkdownEnabled() {
return (bool) get_option(self::POST_OPTION, '');
}
private function isPostRevision($post) {
return $post['post_type'] === 'revision';
}
public function registerSetting() {
add_settings_field(self::POST_OPTION, 'Markdown', [$this, 'postField'], 'writing');
register_setting('writing', self::POST_OPTION, [$this, 'sanitizeSetting']);
}
public function sanitizeSetting($input) {
return (bool) $input;
}
public function postField() {
printf(
'<label><input name="%s" id="%s" type="checkbox"%s> %s</label>',
self::POST_OPTION,
self::POST_OPTION,
checked($this->isPostMarkdownEnabled(), true, false),
esc_html('Use Markdown for posts and pages.')
);
}
private function setAsMarkdown($post_id) {
return update_metadata('post', $post_id, self::IS_MD_META, true);
}
private function swapContent($post) {
$markdown = $post->post_content_filtered;
$post->post_content_filtered = $post->post_content;
$post->post_content = $markdown;
return $post;
}
}
add_action('init', [MarkdownPosts::getInstance(), 'init']);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment