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 12 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
96 changes: 89 additions & 7 deletions inc/class-img-shortcode-data-migration.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

class Img_Shortcode_Data_Migration {

private static function img_shortcode_regex() {
$img_shortcode_regex =
private static function img_tag_regex() {
$img_tag_regex =
'(?:<a[^>]+' .
'href="(?P<href>[^"]*)"' .
'[^>]*>)?' .
Expand All @@ -25,20 +25,24 @@ private static function img_shortcode_regex() {
'[^>]*>' .
'(?:<\/a>)?';

return $img_shortcode_regex;
return $img_tag_regex;
}


private static function caption_shortcode_regex() {
$caption_shortcode_regex =
'\[caption' .
'[^\]]*' . '\]\]?' .
self::img_shortcode_regex() .
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 +61,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 +187,84 @@ 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';

$size = isset( $atts['size'] ) ? $atts['size'] : 'medium';

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

if ( ! isset( $width ) && isset( $atts['attachment'] ) ) {
$attachment = wp_get_attachment_image_src(
(int) $atts['attachment'], $size
);
$width = intval( $attachment[1] );
}

if ( $caption ) {
$content =
'[caption ' .
'id="attachment_' . $atts['attachment'] . '" ' .
'width="' . $width . '" ' .
'align="' . $align . '"' .
']' .
$content .
$caption .
'[/caption]';
}

return $content;
}

/**
* Get a post from a Post ID or post object.
*
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 migrate `wp post list --post_type=post` --ids`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/migrate/revert

*
* ## Converts shortcodes back to images on one post, preserving a log to rollback in case of errors.
* wp image-shortcake migrate 123 > potential-oops.txt
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

*
* @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
75 changes: 75 additions & 0 deletions tests/test-img-shortcode-data-migration.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,81 @@ function test_img_tag_from_attachment() {
$this->assertNotContains( 'src="', $replacements[ $img_tag ] );
}

/**
* Case: [img] shortcode conversion to <img>
*
*/
function test_img_shortcode_conversion_to_img() {

$attachment_id = $this->attachment_id;
$upload_dir = wp_upload_dir();
$expected_src_attr = $upload_dir['url'] . '/fusion_image_placeholder_16x9_h2000.png';

// Test vanilla shortcode
$shortcode = '[img attachment="' . $attachment_id . '" /]';
$conversion = Img_Shortcode_Data_Migration::convert_img_shortcode_to_tag( $shortcode );
$this->assertContains( '<img class="size-full alignnone" src="' . $expected_src_attr . '" width="2000" height="1125" />' , $conversion );

// Test link href: linkto="file"
$shortcode = '[img attachment="' . $attachment_id . '" linkto="file" /]';
$conversion = Img_Shortcode_Data_Migration::convert_img_shortcode_to_tag( $shortcode );
$this->assertContains( 'href="' . $expected_src_attr . '"', $conversion );

// Test link href: linkto="attachment"
$shortcode = '[img attachment="' . $attachment_id . '" linkto="attachment" /]';
$conversion = Img_Shortcode_Data_Migration::convert_img_shortcode_to_tag( $shortcode );
$expected_href_attr = get_permalink( $attachment_id );
$this->assertContains( 'href="' . $expected_href_attr . '"', $conversion );

// Test caption attribute
$caption = <<<EOL
This is a "<em>caption</em>". It should contain <abbr>HTML</abbr> and <span class="icon">markup</span>.
EOL;
$shortcode = '[img attachment="' . $attachment_id . '" caption="' . esc_attr( $caption ) . '" /]';
$conversion = Img_Shortcode_Data_Migration::convert_img_shortcode_to_tag( $shortcode );
$expected_caption = esc_html( $caption );
$this->assertContains( '[caption id="attachment_' . $attachment_id . '" width="300" align="alignnone"]', $conversion );
$this->assertContains( $expected_caption . '[/caption]', $conversion );

// Test no attachment
// @todo Determine ideal behavior here
// $shortcode = '[img caption="' . esc_attr( $caption ) . '" /]';
// $conversion = Img_Shortcode_Data_Migration::convert_img_shortcode_to_tag( $shortcode );

// Test cadillac 1
$shortcode = '[img attachment="' . $attachment_id . '" linkto="attachment" size="full" caption="' . esc_attr( $caption ) . '" align="alignright" /]';
$conversion = Img_Shortcode_Data_Migration::convert_img_shortcode_to_tag( $shortcode );
$expected = '[caption id="attachment_' .
$attachment_id .
'" width="2000" align="alignright"]<a href="' .
$expected_href_attr .
'" ><img class="size-full alignright" src="' .
$expected_src_attr .
'" width="2000" height="1125" /></a>' .
$expected_caption .
'[/caption]';

$this->assertContains( $expected, $conversion );

// Test cadillac 2
$shortcode = '[img attachment="' . $attachment_id . '" linkto="attachment" size="medium" caption="' . esc_attr( $caption ) . '" align="alignnone" /]';
$conversion = Img_Shortcode_Data_Migration::convert_img_shortcode_to_tag( $shortcode );
$expected_src = wp_get_attachment_image_src( $attachment_id, 'medium' );
$expected_src_attr = $expected_src[0];
$expected = '[caption id="attachment_' .
$attachment_id .
'" width="300" align="alignnone"]<a href="' .
$expected_href_attr .
'" ><img class="size-medium alignnone" src="' .
$expected_src_attr .
'" width="300" height="169" /></a>' .
$expected_caption .
'[/caption]';

$this->assertContains( $expected, $conversion );

}

/**
* Case: <img> tags with an external src
*
Expand Down