Skip to content
This repository was archived by the owner on Apr 2, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
517ed1d
Convert [img] shortcodes back to tags/captions
goldenapples May 8, 2015
5a0e9c4
Merge remote-tracking branch 'origin/master' into 20-convert-shortcod…
goldenapples May 19, 2015
930fa79
Rename 'downdate' function to the more sensical 'revert'
goldenapples May 19, 2015
ad1e6ff
Start adding tests for reverse conversion
Aug 11, 2015
25f117f
Merge branch 'master' into 20-convert-shortcodes-to-inline-images
Aug 11, 2015
3a3de08
Fix caption reversal test
Aug 11, 2015
da0b515
PHPCS cleanup for CLI command
Aug 11, 2015
ef7b443
Remove commented test code until it's real
Aug 11, 2015
a44876c
Add some more shortcake conversion tests
Aug 12, 2015
b1a0773
Add first cadillac test
Aug 12, 2015
81ad0ad
Add second cadillac test
Aug 12, 2015
c2ee82c
Remove EOL whitespace
Aug 12, 2015
be4c6e8
Add another test for caption width
Aug 13, 2015
87de98c
Modify the shortcode callback to oupt img w/o src if no attachment
Aug 13, 2015
c678a16
Updates to behavior of the migration script
Aug 13, 2015
e95e9d1
Adds test coverage for missing/invalid attachment ID's
Aug 13, 2015
bcd1c4b
PHPCS tweaks
Aug 13, 2015
c320ffe
Fix WP CLI phpdoc
Aug 13, 2015
619f530
If invalid attachment, store in data attr for posterity
Aug 13, 2015
6d16c9d
Use yoda conditional
Aug 13, 2015
1f8ae43
Scaffold some tests of the regex
Aug 13, 2015
4cd9062
Update callback to model core behavior w/r/t caption + alignment
Aug 14, 2015
882a0c5
Update tests to have alignments in the right spot
Aug 14, 2015
dcba78b
Updates to regex
Aug 14, 2015
6facd5b
Capture caption in the regex
Aug 14, 2015
76b74e5
Revert the logic change to alignment, broke stuff
Aug 14, 2015
cacbb2d
Tweaks to the regex
Aug 14, 2015
171dff5
PHPCS issues
Aug 14, 2015
d835a40
Tweak to regex for readability
Aug 14, 2015
24793a7
Fix another regex naggle
Aug 14, 2015
96df81d
Fix caption regex to get tests passing
Aug 17, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 140 additions & 28 deletions inc/class-img-shortcode-data-migration.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,52 @@

class Img_Shortcode_Data_Migration {

private static function img_shortcode_regex() {
$img_shortcode_regex =
'(?:<a[^>]+' .
'href="(?P<href>[^"]*)"' .
'[^>]*>)?' .
'<img[^>]*' .
'class="' .
'(?|size-(?P<size>\w+))?' . ' ?' .
'(?|wp-image-(?P<attachment>\d+))?' . ' ?' .
'(?|(?P<align>align[\w-]+))?' . ' ?' .
'[^"]*" ' . // end of class attribute
'src="(?P<src>[^"]*)" ?' .
'(?:alt="(?P<alt>[^"]*)" ?)?' .
'(?:width="(?P<width>[^"]*)" ?)?' .
'(?:height="(?P<height>[^"]*)" ?)?' .
'[^>]*>' .
'(?:<\/a>)?';

return $img_shortcode_regex;
public static function img_tag_regex() {
$img_tag_regex = '(?:<a href="' .
'(?P<href>[^"]*)">)?' .
'<img ' .
'src="' .
'(?P<src>[^"]*)?' .
'" (?:alt="' .
'(?P<alt>[^"]*)' .
'" )?' .
'(?:width="' .
'(?P<width>[^"]*)' .
'" )?' .
'(?:height="' .
'(?P<height>[^"]*)' .
'" )?' .
'(?:class="' .
'((?:size-)' .
'(?P<size>[^ "]*)' .
')?' .
'(?:(\s)?wp-image-' .
'(?P<attachment>\d*)' .
')?' .
'(?:' .
'(\s)?' .
'(?P<align>[^"]*)' .
')?' .
'")?' .
' \/>' .
'(?:<\/a>)?';
return $img_tag_regex;
}


private static function caption_shortcode_regex() {
public static function caption_shortcode_regex() {
$caption_shortcode_regex =
'\[caption' .
'[^\]]*' . '\]\]?' .
self::img_shortcode_regex() .
'(?: (?P<caption>[^\]]*))' .
'\[\[?\/caption\]\]?';
'\[caption[^\]]*\]' .
self::img_tag_regex() .
'(?P<caption>[^\[]*)' .
'\[\/caption]';
return $caption_shortcode_regex;
}

private static function img_shortcode_regex() {
$img_shortcode_regex = '\[img ' . '[^\]]*]';
return $img_shortcode_regex;
}

public static function find_img_tags_for_replacement_on_post( $post ) {
if ( ! $post = self::maybe_get_post_from_id( $post ) ) {
return false;
Expand All @@ -57,10 +71,10 @@ public static function find_img_tags_for_replacement( $post_content ) {

$replacements = array();

$img_shortcode_regex = self::img_shortcode_regex();
$img_tag_regex = self::img_tag_regex();

preg_match_all(
"/$img_shortcode_regex/s",
"/$img_tag_regex/s",
$post_content,
$matches,
PREG_SET_ORDER
Expand Down Expand Up @@ -183,6 +197,104 @@ public static function convert_img_tag_to_shortcode( $img_tag, $attributes ) {
}


/**
* Get all [img] shortcodes in a string for replacement.
*
* Used in converting data added by this plugin back to the default format
* of <img> tags and [caption] shortcodes.
*
*/
public static function find_img_shortcodes_for_replacement( $post_content ) {

$replacements = array();

$img_shortcode_regex = self::img_shortcode_regex();

preg_match_all(
"/$img_shortcode_regex/s",
$post_content,
$matches,
PREG_SET_ORDER
);

if ( 0 === count( $matches ) ) {
return array();
}

foreach ( $matches as $matched_pattern ) {
$replacements[ $matched_pattern[0] ] = self::convert_img_shortcode_to_tag(
$matched_pattern[0]
);
}

return $replacements;

}


/**
* Convert an [img] shortcode as inserted by this plugin to the WP default
* representation.
*
* @param string `[img]` shortcode element
* @return string A `[caption]` shortcode element, or an <img> tag
*/
public static function convert_img_shortcode_to_tag( $img_shortcode ) {
$atts = shortcode_parse_atts( $img_shortcode );

$caption = isset( $atts['caption'] ) ? $atts['caption'] : '';
unset( $atts['caption'] );

$width = isset( $atts['width'] ) ? $atts['width'] : null;

$align = isset( $atts['align'] ) ? $atts['align'] : 'alignnone';

// Use a size if set.
// If valid attachment, full is ok
// If not valid, use medium so we can provide width
if ( isset( $atts['size'] ) ) {
$size = $atts['size'];
} else {
if ( isset( $atts['attachment'] ) && get_permalink( $atts['attachment'] ) ) {
$size = $atts['size'] = 'full';
} else {
$size = $atts['size'] = 'large';
}
}

$content = Img_Shortcode::callback( $atts );

if ( ! isset( $width ) && isset( $atts['attachment'] ) && get_permalink( $atts['attachment'] ) ) {
$attachment = wp_get_attachment_image_src(
(int) $atts['attachment'], $size
);
$width = intval( $attachment[1] );
} else {
/* If there's no width set and no valid attachment to get full/custom size dimensions from, fallback to large width */
$width = '600';
}

if ( isset( $atts['attachment'] ) && $caption ) {
$id_string = 'id="attachment_' . esc_attr( sanitize_html_class( $atts['attachment'] ) ). '" ';
} else {
$id_string = '';
}

if ( $caption ) {
$content =
'[caption ' .
$id_string .
'width="' . $width . '" ' .
'align="' . $align . '"' .
']' .
$content .
$caption .
'[/caption]';
}

return $content;
}

/**
* Get a post from a Post ID or post object.
*
Expand Down
19 changes: 15 additions & 4 deletions inc/class-img-shortcode.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ public static function reversal( $content ) {
*
* @param array $attrs Shortcode attributes. See definitions in
* @function `get_shortcode_ui_args()`
*
* @return string
*/
public static function callback( $attr ) {
Expand Down Expand Up @@ -190,7 +191,12 @@ public static function callback( $attr ) {
} else if ( ! empty( $attr['src'] ) ) {
$image_attr['src'] = esc_url( $attr['src'] );
} else {
return; // An image without a src isn't much of an image
$image_attr['src'] = '';
}

// If the attachment is invalid, store it in an `data-shortcode-attachment` attr for posterity
if ( '' === $image_attr['src'] && isset( $attr['attachment'] ) ) {
$image_attr['data-shortcode-attachment'] = $attr['attachment'];
}

foreach ( $image_attr as $attr_name => $attr_value ) {
Expand Down Expand Up @@ -225,6 +231,7 @@ public static function callback( $attr ) {
$image_html = apply_filters( 'img_shortcode_output_after_linkify', $image_html, $attr );

// If a caption is specified, wrap the image in the appropriat caption markup.
// When migrating, captioning is handled in the migration script
if ( ! empty( $attr['caption'] ) ) {

// The WP caption element requires a width defined
Expand Down Expand Up @@ -259,15 +266,19 @@ public static function callback( $attr ) {
*/
private static function linkify( $img_tag, $attributes ) {

$_id = intval( $attributes['attachment'] );
if ( isset( $attributes['attachment'] ) && get_permalink( $attributes['attachment'] ) ) {
$_id = intval( $attributes['attachment'] );
} else {
$_id = false;
}

$link_attrs = array();

if ( isset( $attributes['url'] ) ) {
$link_attrs['href'] = esc_url( $attributes['url'] );
} else if ( ! empty( $attributes['linkto'] ) && 'attachment' === $attributes['linkto'] ) {
} else if ( ! empty( $attributes['linkto'] ) && 'attachment' === $attributes['linkto'] && $_id ) {
$link_attrs['href'] = get_permalink( $_id );
} elseif ( ! empty( $attributes['linkto'] ) && 'file' === $attributes['linkto'] ) {
} elseif ( ! empty( $attributes['linkto'] ) && 'file' === $attributes['linkto'] && $_id ) {
$attachment_src = wp_get_attachment_image_src( $_id, 'full', false, $attributes );
$link_attrs['href'] = $attachment_src[0];
} else {
Expand Down
82 changes: 81 additions & 1 deletion inc/class-wp-cli-img-shortcode-command.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function __construct() {
* ## EXAMPLES
*
* ## Migrate all Posts to the Image Shortcake syntax
* wp image-shortcake-shortcode migrate `wp post list --post_type=post` --ids`
* wp image-shortcake migrate `wp post list --post_type=post` --ids`
*
* ## Converts images to shortcodes on one post, preserving a log to rollback in case of errors.
* wp image-shortcake migrate 123 > potential-oops.txt
Expand Down Expand Up @@ -102,6 +102,86 @@ public function migrate( $args, $assoc_args ) {

}


/**
* Revert post content from image shortcodes back to <img> tags and [caption] shortcodes
*
* ## OPTIONS
*
* <id>...
* : One or more IDs of posts to update.
*
* [--dry-run]
* : Only show the content which is to be changed, don't update posts.
*
* ## EXAMPLES
*
* ## Revert all Posts from the Image Shortcake syntax
* wp image-shortcake revert `wp post list --post_type=post` --ids`
*
* ## Converts shortcodes back to images on one post, preserving a log to rollback in case of errors.
* wp image-shortcake revert 123 > potential-oops.txt
*
* @synopsis <id>... [--dry-run]
*/
public function revert( $args, $assoc_args ) {

foreach ( array_filter( $args ) as $post_ID ) {

$post = $this->fetcher->get_check( $post_ID );

$_content = $post->post_content;

$replacements = Img_Shortcode_Data_Migration::find_img_shortcodes_for_replacement( $_content );

$_content = str_replace(
array_keys( $replacements ),
array_values( $replacements ),
$_content
);

WP_CLI::log( '' );

if ( 0 === count( $replacements ) ) {
WP_CLI::log( 'Nothing to replace on post ' . $post->ID . '. Skipping.' );
WP_CLI::log( '' );
continue;
}

$header = 'Image shortcode replacements for post ' . $post->ID;

WP_CLI::log( $header );
WP_CLI::log( str_repeat( '=', strlen( $header ) ) );
WP_CLI::log( '' );

foreach ( $replacements as $del => $ins ) {
\WP_CLI::log( \cli\Colors::colorize( '%C-%n' ) . $del, true );
\WP_CLI::log( \cli\Colors::colorize( '%G+%n' ) . $ins, true );
}

WP_CLI::log( '' );

if ( isset( $assoc_args['dry-run'] ) ) {
WP_CLI::log( 'Post not updated: --dry-run specifed.' );
WP_CLI::log( '' );
continue;
}

global $wpdb;

// @codingStandardsIgnoreStart
$updated = $wpdb->update( $wpdb->posts, array( 'post_content' => $_content ), array( 'ID' => $post_ID ) );
// @codingStandardsIgnoreEnd

if ( 1 === $updated ) {
clean_post_cache( $post );
WP_CLI::success( 'Updated post ' . $post->ID . '.' );
} else {
WP_CLI::warning( 'There was an unexpected error updating post ' . $post->ID . '.' );
}
}
}

}


Expand Down
Loading