Edit File by line
/home/zeestwma/richards.../wp-conte.../plugins/jetpack/modules/markdown
File: easy-markdown.php
if ( preg_match( $re, $tag ) ) {
[500] Fix | Delete
$attributes['markdown'] = true;
[501] Fix | Delete
$tags[ $tag ] = $attributes;
[502] Fix | Delete
}
[503] Fix | Delete
}
[504] Fix | Delete
[505] Fix | Delete
return $tags;
[506] Fix | Delete
}
[507] Fix | Delete
[508] Fix | Delete
/**
[509] Fix | Delete
* TinyMCE needs to know not to strip the 'markdown' attribute. Unfortunately, it doesn't
[510] Fix | Delete
* really offer a nice API for allowed attributes, so we have to manually add it
[511] Fix | Delete
* to the schema instead.
[512] Fix | Delete
*/
[513] Fix | Delete
public function after_wp_tiny_mce() {
[514] Fix | Delete
?>
[515] Fix | Delete
<script type="text/javascript">
[516] Fix | Delete
jQuery( function() {
[517] Fix | Delete
( 'undefined' !== typeof tinymce ) && tinymce.on( 'AddEditor', function( event ) {
[518] Fix | Delete
event.editor.on( 'BeforeSetContent', function( event ) {
[519] Fix | Delete
var editor = event.target;
[520] Fix | Delete
Object.keys( editor.schema.elements ).forEach( function( key, index ) {
[521] Fix | Delete
editor.schema.elements[ key ].attributes['markdown'] = {};
[522] Fix | Delete
editor.schema.elements[ key ].attributesOrder.push( 'markdown' );
[523] Fix | Delete
} );
[524] Fix | Delete
} );
[525] Fix | Delete
}, true );
[526] Fix | Delete
} );
[527] Fix | Delete
</script>
[528] Fix | Delete
<?php
[529] Fix | Delete
}
[530] Fix | Delete
[531] Fix | Delete
/**
[532] Fix | Delete
* Magic happens here. Markdown is converted and stored on post_content. Original Markdown is stored
[533] Fix | Delete
* in post_content_filtered so that we can continue editing as Markdown.
[534] Fix | Delete
*
[535] Fix | Delete
* @param array $post_data The post data that will be inserted into the DB. Slashed.
[536] Fix | Delete
* @param array $postarr All the stuff that was in $_POST.
[537] Fix | Delete
* @return array $post_data with post_content and post_content_filtered modified
[538] Fix | Delete
*/
[539] Fix | Delete
public function wp_insert_post_data( $post_data, $postarr ) {
[540] Fix | Delete
// $post_data array is slashed!
[541] Fix | Delete
$post_id = isset( $postarr['ID'] ) ? $postarr['ID'] : false;
[542] Fix | Delete
// bail early if markdown is disabled or this post type is unsupported.
[543] Fix | Delete
if ( ! $this->is_posting_enabled() || ! post_type_supports( $post_data['post_type'], self::POST_TYPE_SUPPORT ) ) {
[544] Fix | Delete
// it's disabled, but maybe this *was* a markdown post before.
[545] Fix | Delete
if ( $this->is_markdown( $post_id ) && ! empty( $post_data['post_content_filtered'] ) ) {
[546] Fix | Delete
$post_data['post_content_filtered'] = '';
[547] Fix | Delete
}
[548] Fix | Delete
// we have no context to determine supported post types in the `post_content_pre` hook,
[549] Fix | Delete
// which already ran to sanitize code blocks. Undo that.
[550] Fix | Delete
$post_data['post_content'] = $this->get_parser()->codeblock_restore( $post_data['post_content'] );
[551] Fix | Delete
return $post_data;
[552] Fix | Delete
}
[553] Fix | Delete
// rejigger post_content and post_content_filtered
[554] Fix | Delete
// revisions are already in the right place, except when we're restoring, but that's taken care of elsewhere
[555] Fix | Delete
// also prevent quick edit feature from overriding already-saved markdown (issue https://github.com/Automattic/jetpack/issues/636).
[556] Fix | Delete
if ( 'revision' !== $post_data['post_type'] && ! isset( $_POST['_inline_edit'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
[557] Fix | Delete
/**
[558] Fix | Delete
* Filter the original post content passed to Markdown.
[559] Fix | Delete
*
[560] Fix | Delete
* @module markdown
[561] Fix | Delete
*
[562] Fix | Delete
* @since 2.8.0
[563] Fix | Delete
*
[564] Fix | Delete
* @param string $post_data['post_content'] Untransformed post content.
[565] Fix | Delete
*/
[566] Fix | Delete
$post_data['post_content_filtered'] = apply_filters( 'wpcom_untransformed_content', $post_data['post_content'] );
[567] Fix | Delete
$post_data['post_content'] = $this->transform( $post_data['post_content'], array( 'id' => $post_id ) );
[568] Fix | Delete
/** This filter is already documented in core/wp-includes/default-filters.php */
[569] Fix | Delete
$post_data['post_content'] = apply_filters( 'content_save_pre', $post_data['post_content'] );
[570] Fix | Delete
} elseif ( str_starts_with( $post_data['post_name'], $post_data['post_parent'] . '-autosave' ) ) {
[571] Fix | Delete
// autosaves for previews are weird.
[572] Fix | Delete
/** This filter is already documented in modules/markdown/easy-markdown.php */
[573] Fix | Delete
$post_data['post_content_filtered'] = apply_filters( 'wpcom_untransformed_content', $post_data['post_content'] );
[574] Fix | Delete
$post_data['post_content'] = $this->transform( $post_data['post_content'], array( 'id' => $post_data['post_parent'] ) );
[575] Fix | Delete
/** This filter is already documented in core/wp-includes/default-filters.php */
[576] Fix | Delete
$post_data['post_content'] = apply_filters( 'content_save_pre', $post_data['post_content'] );
[577] Fix | Delete
}
[578] Fix | Delete
[579] Fix | Delete
// set as markdown on the wp_insert_post hook later.
[580] Fix | Delete
if ( $post_id ) {
[581] Fix | Delete
$this->monitoring['post'][ $post_id ] = true;
[582] Fix | Delete
} else {
[583] Fix | Delete
$this->monitoring['content'] = wp_unslash( $post_data['post_content'] );
[584] Fix | Delete
}
[585] Fix | Delete
if ( 'revision' === $postarr['post_type'] && $this->is_markdown( $postarr['post_parent'] ) ) {
[586] Fix | Delete
$this->monitoring['parent'][ $postarr['post_parent'] ] = true;
[587] Fix | Delete
}
[588] Fix | Delete
[589] Fix | Delete
return $post_data;
[590] Fix | Delete
}
[591] Fix | Delete
[592] Fix | Delete
/**
[593] Fix | Delete
* Calls on wp_insert_post action, after wp_insert_post_data. This way we can
[594] Fix | Delete
* still set postmeta on our revisions after it's all been deleted.
[595] Fix | Delete
*
[596] Fix | Delete
* @param int $post_id The post ID that has just been added/updated.
[597] Fix | Delete
*/
[598] Fix | Delete
public function wp_insert_post( $post_id ) {
[599] Fix | Delete
$post_parent = get_post_field( 'post_parent', $post_id );
[600] Fix | Delete
// this didn't have an ID yet. Compare the content that was just saved.
[601] Fix | Delete
if ( isset( $this->monitoring['content'] ) && get_post_field( 'post_content', $post_id ) === $this->monitoring['content'] ) {
[602] Fix | Delete
unset( $this->monitoring['content'] );
[603] Fix | Delete
$this->set_as_markdown( $post_id );
[604] Fix | Delete
}
[605] Fix | Delete
if ( isset( $this->monitoring['post'][ $post_id ] ) ) {
[606] Fix | Delete
unset( $this->monitoring['post'][ $post_id ] );
[607] Fix | Delete
$this->set_as_markdown( $post_id );
[608] Fix | Delete
} elseif ( isset( $this->monitoring['parent'][ $post_parent ] ) ) {
[609] Fix | Delete
unset( $this->monitoring['parent'][ $post_parent ] );
[610] Fix | Delete
$this->set_as_markdown( $post_id );
[611] Fix | Delete
}
[612] Fix | Delete
}
[613] Fix | Delete
[614] Fix | Delete
/**
[615] Fix | Delete
* Run a comment through Markdown. Easy peasy.
[616] Fix | Delete
*
[617] Fix | Delete
* @param string $content - the content.
[618] Fix | Delete
* @return string
[619] Fix | Delete
*/
[620] Fix | Delete
public function pre_comment_content( $content ) {
[621] Fix | Delete
return $this->transform(
[622] Fix | Delete
$content,
[623] Fix | Delete
array(
[624] Fix | Delete
'id' => $this->comment_hash( $content ),
[625] Fix | Delete
)
[626] Fix | Delete
);
[627] Fix | Delete
}
[628] Fix | Delete
[629] Fix | Delete
/**
[630] Fix | Delete
* Return a comment hash.
[631] Fix | Delete
*
[632] Fix | Delete
* @param string $content - the content of the comment.
[633] Fix | Delete
*/
[634] Fix | Delete
protected function comment_hash( $content ) {
[635] Fix | Delete
return 'c-' . substr( md5( $content ), 0, 8 );
[636] Fix | Delete
}
[637] Fix | Delete
[638] Fix | Delete
/**
[639] Fix | Delete
* Markdown conversion. Some DRYness for repetitive tasks.
[640] Fix | Delete
*
[641] Fix | Delete
* @param string $text Content to be run through Markdown.
[642] Fix | Delete
* @param array $args Arguments, with keys:
[643] Fix | Delete
* id: provide a string to prefix footnotes with a unique identifier
[644] Fix | Delete
* unslash: when true, expects and returns slashed data
[645] Fix | Delete
* decode_code_blocks: when true, assume that text in fenced code blocks is already
[646] Fix | Delete
* HTML encoded and should be decoded before being passed to Markdown, which does
[647] Fix | Delete
* its own encoding.
[648] Fix | Delete
* @return string Markdown-processed content
[649] Fix | Delete
*/
[650] Fix | Delete
public function transform( $text, $args = array() ) {
[651] Fix | Delete
// If this contains Gutenberg content, let's keep it intact.
[652] Fix | Delete
if ( has_blocks( $text ) ) {
[653] Fix | Delete
return $text;
[654] Fix | Delete
}
[655] Fix | Delete
[656] Fix | Delete
$args = wp_parse_args(
[657] Fix | Delete
$args,
[658] Fix | Delete
array(
[659] Fix | Delete
'id' => false,
[660] Fix | Delete
'unslash' => true,
[661] Fix | Delete
'decode_code_blocks' => ! $this->get_parser()->use_code_shortcode,
[662] Fix | Delete
)
[663] Fix | Delete
);
[664] Fix | Delete
// probably need to unslash.
[665] Fix | Delete
if ( $args['unslash'] ) {
[666] Fix | Delete
$text = wp_unslash( $text );
[667] Fix | Delete
}
[668] Fix | Delete
[669] Fix | Delete
/**
[670] Fix | Delete
* Filter the content to be run through Markdown, before it's transformed by Markdown.
[671] Fix | Delete
*
[672] Fix | Delete
* @module markdown
[673] Fix | Delete
*
[674] Fix | Delete
* @since 2.8.0
[675] Fix | Delete
*
[676] Fix | Delete
* @param string $text Content to be run through Markdown
[677] Fix | Delete
* @param array $args Array of Markdown options.
[678] Fix | Delete
*/
[679] Fix | Delete
$text = apply_filters( 'wpcom_markdown_transform_pre', $text, $args ) ?? '';
[680] Fix | Delete
// ensure our paragraphs are separated.
[681] Fix | Delete
$text = str_replace( array( '</p><p>', "</p>\n<p>" ), "</p>\n\n<p>", $text );
[682] Fix | Delete
// visual editor likes to add <p>s. Buh-bye.
[683] Fix | Delete
$text = $this->get_parser()->unp( $text );
[684] Fix | Delete
// sometimes we get an encoded > at start of line, breaking blockquotes.
[685] Fix | Delete
$text = preg_replace( '/^&gt;/m', '>', $text );
[686] Fix | Delete
// prefixes are because we need to namespace footnotes by post_id.
[687] Fix | Delete
$this->get_parser()->fn_id_prefix = $args['id'] ? $args['id'] . '-' : '';
[688] Fix | Delete
// If we're not using the code shortcode, prevent over-encoding.
[689] Fix | Delete
if ( $args['decode_code_blocks'] ) {
[690] Fix | Delete
$text = $this->get_parser()->codeblock_restore( $text );
[691] Fix | Delete
}
[692] Fix | Delete
// Transform it!
[693] Fix | Delete
$text = $this->get_parser()->transform( $text );
[694] Fix | Delete
// Fix footnotes - kses doesn't like the : IDs it supplies.
[695] Fix | Delete
$text = preg_replace( '/((id|href)="#?fn(ref)?):/', '$1-', $text );
[696] Fix | Delete
// Markdown inserts extra spaces to make itself work. Buh-bye.
[697] Fix | Delete
$text = rtrim( $text );
[698] Fix | Delete
/**
[699] Fix | Delete
* Filter the content to be run through Markdown, after it was transformed by Markdown.
[700] Fix | Delete
*
[701] Fix | Delete
* @module markdown
[702] Fix | Delete
*
[703] Fix | Delete
* @since 2.8.0
[704] Fix | Delete
*
[705] Fix | Delete
* @param string $text Content to be run through Markdown
[706] Fix | Delete
* @param array $args Array of Markdown options.
[707] Fix | Delete
*/
[708] Fix | Delete
$text = apply_filters( 'wpcom_markdown_transform_post', $text, $args );
[709] Fix | Delete
[710] Fix | Delete
// probably need to re-slash.
[711] Fix | Delete
if ( $args['unslash'] ) {
[712] Fix | Delete
$text = wp_slash( $text );
[713] Fix | Delete
}
[714] Fix | Delete
[715] Fix | Delete
return $text;
[716] Fix | Delete
}
[717] Fix | Delete
[718] Fix | Delete
/**
[719] Fix | Delete
* Shows Markdown in the Revisions screen, and ensures that post_content_filtered
[720] Fix | Delete
* is maintained on revisions
[721] Fix | Delete
*
[722] Fix | Delete
* @param array $fields Post fields pertinent to revisions.
[723] Fix | Delete
*/
[724] Fix | Delete
public function wp_post_revision_fields( $fields ) {
[725] Fix | Delete
$fields['post_content_filtered'] = __( 'Markdown content', 'jetpack' );
[726] Fix | Delete
return $fields;
[727] Fix | Delete
}
[728] Fix | Delete
[729] Fix | Delete
/**
[730] Fix | Delete
* Do some song and dance to keep all post_content and post_content_filtered content
[731] Fix | Delete
* in the expected place when a post revision is restored.
[732] Fix | Delete
*
[733] Fix | Delete
* @param int $post_id The post ID have a restore done to it.
[734] Fix | Delete
* @param int $revision_id The revision ID being restored.
[735] Fix | Delete
*/
[736] Fix | Delete
public function wp_restore_post_revision( $post_id, $revision_id ) {
[737] Fix | Delete
if ( $this->is_markdown( $revision_id ) ) {
[738] Fix | Delete
$revision = get_post( $revision_id, ARRAY_A );
[739] Fix | Delete
$post = get_post( $post_id, ARRAY_A );
[740] Fix | Delete
$post['post_content'] = $revision['post_content_filtered']; // Yes, we put it in post_content, because our wp_insert_post_data() expects that.
[741] Fix | Delete
// set this flag so we can restore the post_content_filtered on the last revision later.
[742] Fix | Delete
$this->monitoring['restore'] = true;
[743] Fix | Delete
// let's not make a revision of our fixing update.
[744] Fix | Delete
add_filter( 'wp_revisions_to_keep', '__return_false', 99 );
[745] Fix | Delete
wp_update_post( $post );
[746] Fix | Delete
$this->fix_latest_revision_on_restore( $post_id );
[747] Fix | Delete
remove_filter( 'wp_revisions_to_keep', '__return_false', 99 );
[748] Fix | Delete
}
[749] Fix | Delete
}
[750] Fix | Delete
[751] Fix | Delete
/**
[752] Fix | Delete
* We need to ensure the last revision has Markdown, not HTML in its post_content_filtered
[753] Fix | Delete
* column after a restore.
[754] Fix | Delete
*
[755] Fix | Delete
* @param int $post_id The post ID that was just restored.
[756] Fix | Delete
*/
[757] Fix | Delete
protected function fix_latest_revision_on_restore( $post_id ) {
[758] Fix | Delete
global $wpdb;
[759] Fix | Delete
$post = get_post( $post_id );
[760] Fix | Delete
$last_revision = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_type = 'revision' AND post_parent = %d ORDER BY ID DESC", $post->ID ) );
[761] Fix | Delete
$last_revision->post_content_filtered = $post->post_content_filtered;
[762] Fix | Delete
wp_insert_post( (array) $last_revision );
[763] Fix | Delete
}
[764] Fix | Delete
[765] Fix | Delete
/**
[766] Fix | Delete
* Kicks off magic for an XML-RPC session. We want to keep editing Markdown
[767] Fix | Delete
* and publishing HTML.
[768] Fix | Delete
*
[769] Fix | Delete
* @param string $xmlrpc_method The current XML-RPC method.
[770] Fix | Delete
*/
[771] Fix | Delete
public function xmlrpc_actions( $xmlrpc_method ) {
[772] Fix | Delete
switch ( $xmlrpc_method ) {
[773] Fix | Delete
case 'metaWeblog.getRecentPosts':
[774] Fix | Delete
case 'wp.getPosts':
[775] Fix | Delete
case 'wp.getPages':
[776] Fix | Delete
add_action( 'parse_query', array( $this, 'make_filterable' ), 10, 1 );
[777] Fix | Delete
break;
[778] Fix | Delete
case 'wp.getPost':
[779] Fix | Delete
$this->prime_post_cache();
[780] Fix | Delete
break;
[781] Fix | Delete
}
[782] Fix | Delete
}
[783] Fix | Delete
[784] Fix | Delete
/**
[785] Fix | Delete
* Function metaWeblog.getPost and wp.getPage fire xmlrpc_call action *after* get_post() is called.
[786] Fix | Delete
* So, we have to detect those methods and prime the post cache early.
[787] Fix | Delete
*
[788] Fix | Delete
* @return null
[789] Fix | Delete
*/
[790] Fix | Delete
protected function check_for_early_methods() {
[791] Fix | Delete
$raw_post_data = file_get_contents( 'php://input' );
[792] Fix | Delete
if ( ! str_contains( $raw_post_data, 'metaWeblog.getPost' )
[793] Fix | Delete
&& ! str_contains( $raw_post_data, 'wp.getPage' ) ) {
[794] Fix | Delete
return;
[795] Fix | Delete
}
[796] Fix | Delete
include_once ABSPATH . WPINC . '/class-IXR.php';
[797] Fix | Delete
$message = new IXR_Message( $raw_post_data );
[798] Fix | Delete
$message->parse();
[799] Fix | Delete
$post_id_position = 'metaWeblog.getPost' === $message->methodName ? 0 : 1; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
[800] Fix | Delete
$this->prime_post_cache( $message->params[ $post_id_position ] ?? false );
[801] Fix | Delete
}
[802] Fix | Delete
[803] Fix | Delete
/**
[804] Fix | Delete
* Prime the post cache with swapped post_content. This is a sneaky way of getting around
[805] Fix | Delete
* the fact that there are no good hooks to call on the *.getPost xmlrpc methods.
[806] Fix | Delete
*
[807] Fix | Delete
* @param bool $post_id - the post ID that we're priming.
[808] Fix | Delete
*/
[809] Fix | Delete
private function prime_post_cache( $post_id = false ) {
[810] Fix | Delete
global $wp_xmlrpc_server;
[811] Fix | Delete
if ( ! $post_id ) {
[812] Fix | Delete
if ( isset( $wp_xmlrpc_server->message->params[3] ) ) {
[813] Fix | Delete
$post_id = $wp_xmlrpc_server->message->params[3];
[814] Fix | Delete
} else {
[815] Fix | Delete
return; // Exit early if we can't get a valid post_id
[816] Fix | Delete
}
[817] Fix | Delete
}
[818] Fix | Delete
[819] Fix | Delete
// prime the post cache.
[820] Fix | Delete
if ( $this->is_markdown( $post_id ) ) {
[821] Fix | Delete
$post = get_post( $post_id );
[822] Fix | Delete
if ( ! empty( $post->post_content_filtered ) ) {
[823] Fix | Delete
wp_cache_delete( $post->ID, 'posts' );
[824] Fix | Delete
$post = $this->swap_for_editing( $post );
[825] Fix | Delete
wp_cache_add( $post->ID, $post, 'posts' );
[826] Fix | Delete
$this->posts_to_uncache[] = $post_id;
[827] Fix | Delete
}
[828] Fix | Delete
}
[829] Fix | Delete
// uncache munged posts if using a persistent object cache.
[830] Fix | Delete
if ( wp_using_ext_object_cache() ) {
[831] Fix | Delete
add_action( 'shutdown', array( $this, 'uncache_munged_posts' ) );
[832] Fix | Delete
}
[833] Fix | Delete
}
[834] Fix | Delete
[835] Fix | Delete
/**
[836] Fix | Delete
* Swaps `post_content_filtered` back to `post_content` for editing purposes.
[837] Fix | Delete
*
[838] Fix | Delete
* @param object $post WP_Post object.
[839] Fix | Delete
* @return object WP_Post object with swapped `post_content_filtered` and `post_content`.
[840] Fix | Delete
*/
[841] Fix | Delete
protected function swap_for_editing( $post ) {
[842] Fix | Delete
$markdown = $post->post_content_filtered;
[843] Fix | Delete
// unencode encoded code blocks.
[844] Fix | Delete
$markdown = $this->get_parser()->codeblock_restore( $markdown );
[845] Fix | Delete
// restore beginning of line blockquotes.
[846] Fix | Delete
$markdown = preg_replace( '/^&gt; /m', '> ', $markdown );
[847] Fix | Delete
$post->post_content_filtered = $post->post_content;
[848] Fix | Delete
$post->post_content = $markdown;
[849] Fix | Delete
return $post;
[850] Fix | Delete
}
[851] Fix | Delete
[852] Fix | Delete
/**
[853] Fix | Delete
* We munge the post cache to serve proper markdown content to XML-RPC clients.
[854] Fix | Delete
* Uncache these after the XML-RPC session ends.
[855] Fix | Delete
*/
[856] Fix | Delete
public function uncache_munged_posts() {
[857] Fix | Delete
// $this context gets lost in testing sometimes. Weird.
[858] Fix | Delete
foreach ( self::get_instance()->posts_to_uncache as $post_id ) {
[859] Fix | Delete
wp_cache_delete( $post_id, 'posts' );
[860] Fix | Delete
}
[861] Fix | Delete
}
[862] Fix | Delete
[863] Fix | Delete
/**
[864] Fix | Delete
* Since *.(get)?[Rr]ecentPosts calls get_posts with suppress filters on, we need to
[865] Fix | Delete
* turn them back on so that we can swap things for editing.
[866] Fix | Delete
*
[867] Fix | Delete
* @param object $wp_query WP_Query object.
[868] Fix | Delete
*/
[869] Fix | Delete
public function make_filterable( $wp_query ) {
[870] Fix | Delete
$wp_query->set( 'suppress_filters', false );
[871] Fix | Delete
add_action( 'the_posts', array( $this, 'the_posts' ), 10, 2 );
[872] Fix | Delete
}
[873] Fix | Delete
[874] Fix | Delete
/**
[875] Fix | Delete
* Swaps post_content and post_content_filtered for editing.
[876] Fix | Delete
*
[877] Fix | Delete
* @param array $posts Posts returned by the just-completed query.
[878] Fix | Delete
* @return array Modified $posts
[879] Fix | Delete
*/
[880] Fix | Delete
public function the_posts( $posts ) {
[881] Fix | Delete
foreach ( $posts as $key => $post ) {
[882] Fix | Delete
if ( $this->is_markdown( $post->ID ) && ! empty( $posts[ $key ]->post_content_filtered ) ) {
[883] Fix | Delete
$markdown = $posts[ $key ]->post_content_filtered;
[884] Fix | Delete
$posts[ $key ]->post_content_filtered = $posts[ $key ]->post_content;
[885] Fix | Delete
$posts[ $key ]->post_content = $markdown;
[886] Fix | Delete
}
[887] Fix | Delete
}
[888] Fix | Delete
return $posts;
[889] Fix | Delete
}
[890] Fix | Delete
[891] Fix | Delete
/**
[892] Fix | Delete
* Singleton silence is golden
[893] Fix | Delete
*/
[894] Fix | Delete
private function __construct() {}
[895] Fix | Delete
}
[896] Fix | Delete
[897] Fix | Delete
add_action( 'init', array( WPCom_Markdown::get_instance(), 'load' ) );
[898] Fix | Delete
[899] Fix | Delete
12
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function