Last active
December 12, 2015 21:49
-
-
Save vralle/1f9a79a42d0c35f3b00f to your computer and use it in GitHub Desktop.
Convert images to Shortcode
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php namespace Vralle\Plugin\Shortcode\Img; | |
/*------------------------------------------------------------------- | |
* Convert images to Shortcode | |
*-----------------------------------------------------------------*/ | |
function html_to_shortcode( $content ) { | |
// Returns, if content is empty | |
if( empty( $content ) ) return $content; | |
if( 'content_save_pre' === current_filter() ) | |
$content = stripslashes( $content ); | |
// Ignore DOMDocument errors On | |
libxml_use_internal_errors(true) AND libxml_clear_errors(); | |
$html = new \DOMDocument( '1.0', 'UTF-8' ); | |
// Load HTML as Document Fragment | |
// $html->loadHTML( mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' ), LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED ); | |
$html->loadHTML( mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' ) ); | |
$imgs = $html->getElementsByTagName( 'img' ); | |
// Exit, If nothing | |
if( $imgs->length === 0 ) | |
return $content; | |
// DOMDocument has a strange result for DOM manipulation in Loop. But strange Loop work perfect) | |
for( $i = $imgs->length - 1; $i >= 0; $i-- ) { | |
$image_attr_arr = []; | |
$link_attr_arr = []; | |
foreach( $imgs[$i]->attributes as $attr ) { | |
$image_attr_arr[ $attr->nodeName ] = $attr->nodeValue; | |
} | |
// Go to next image, if empty | |
if ( empty( $image_attr_arr[ 'src' ] ) ) { | |
continue; | |
} else { | |
// convert relative url to absolute | |
$image_attr_arr[ 'src' ] = rel2abs( $image_attr_arr[ 'src' ] ); | |
} | |
// Check parent link | |
$parent = $imgs[$i]->parentNode; | |
// If link: | |
if( 'a' === $parent->nodeName ) { | |
// Save attributes | |
foreach( $parent->attributes as $attr ) { | |
if ( 'href' === $attr->nodeName ) { | |
$link_attr_arr[ 'url' ] = $attr->nodeValue; | |
} else { | |
$link_attr_arr[ 'link_' . $attr->nodeName ] = $attr->nodeValue; | |
} | |
} | |
} | |
// Get Attachment ID and Size | |
$attachment = get_attachment_id( $image_attr_arr['src'] ); | |
// Set id | |
if( !empty( $attachment['id'] ) ) { | |
$image_attr_arr['attachment'] = $attachment['id']; | |
$image_attr_arr['size'] = $attachment['size']; | |
unset( $image_attr_arr['width'] ); | |
unset( $image_attr_arr['height'] ); | |
unset( $image_attr_arr['alt'] ); | |
} else { | |
// remove id attrs | |
if( !empty( $image_attr_arr['class'] ) ) { | |
$image_attr_arr['class'] = preg_replace( '/wp-image-\d+/i', '', $image_attr_arr['class'] ); | |
$image_attr_arr['class'] = preg_replace( '/size-\w+/i', '', $image_attr_arr['class'] ); | |
} | |
unset( $image_attr_arr['attachment'] ); | |
unset( $image_attr_arr['size'] ); | |
// Check broken Images | |
if ( $size = @getimagesize( $src ) ) { | |
list( $width, $height ) = $size; | |
if ( empty( $image_attr_arr['width'] ) ) { | |
$image_attr_arr['width'] = $width; | |
} | |
if ( empty( $image_attr_arr['height'] ) ) { | |
$image_attr_arr['height'] = $height; | |
} | |
} | |
} | |
// Set align | |
if( !empty( $image_attr_arr['class'] ) ) { | |
if( preg_match( '/align(\w+)/i', $image_attr_arr['class'], $align ) ) { | |
$image_attr_arr['align'] = $align[1]; | |
// remove align from class | |
$image_attr_arr['class'] = str_replace( $align[0], '', $image_attr_arr['class'] ); | |
} | |
} | |
unset( $image_attr_arr['class'] ); | |
// links checker | |
if( !empty( $link_attr_arr['url'] ) ) { | |
$link_attr_arr['url'] = rel2abs( $link_attr_arr['url'] ); | |
if( isset( $image_attr_arr['attachment'] ) ) { | |
// Check link to post | |
if ( $link_attr_arr['url'] === get_attachment_link( $image_attr_arr['attachment'] ) ) { | |
$link_attr_arr['linkto'] = 'post'; | |
// Check link to file | |
} elseif ( $link_attr_arr['url'] === wp_get_attachment_url( $image_attr_arr['attachment'] ) ) { | |
$link_attr_arr['linkto'] = 'file'; | |
} | |
// Remove url | |
unset( $link_attr_arr['url'] ); | |
} else { | |
$link_attr_arr['linkto'] = 'custom'; | |
// Cleanup rel attrs | |
if( !empty( $link_attr_arr['rel'] ) ) { | |
$link_attr_arr['rel'] = preg_replace( '/attachment[\s+]?/i', '', $link_attr_arr['rel'] ); | |
$link_attr_arr['rel'] = preg_replace( '/wp-att-[\d+][\s+]?/i', '', $link_attr_arr['rel'] ); | |
} | |
} | |
} | |
$output = '[img'; | |
foreach ( $image_attr_arr as $name => $value ) { | |
$output .= sprintf( ' %s="%s"', sanitize_key( $name ), esc_attr( $value ) ); | |
} | |
if( !empty( $link_attr_arr ) ) { | |
foreach ( $link_attr_arr as $name => $value ) { | |
if( false !== array_search( $name, ['url', 'target', 'linkto'] ) ) { | |
$output .= sprintf( ' %s="%s"', sanitize_key( $name ), esc_attr( $value ) ); | |
} else { | |
$output .= sprintf( ' link_%s="%s"', sanitize_key( $name ), esc_attr( $value ) ); | |
} | |
} | |
} | |
$output .= ']'; | |
// Create output | |
$shortcode = $html->createTextNode( $output ); | |
if( !empty( $link_attr_arr ) ) { | |
$parent->parentNode->replaceChild( $shortcode, $parent ); | |
} else { | |
$imgs[$i]->parentNode->replaceChild( $shortcode, $imgs[$i] ); | |
} | |
} | |
$html->saveHTML( $html ); | |
$content = $html->textContent; | |
if( 'content_save_pre' === current_filter() ) | |
return addslashes( $content ); | |
return $content; | |
} | |
add_filter( 'content_save_pre', __NAMESPACE__ . '\\html_to_shortcode', 1 ); | |
// add_filter( 'content_edit_pre', __NAMESPACE__ . '\\html_to_shortcode' ); | |
function shortcode2html( $content ) { | |
preg_match_all( '/' . get_shortcode_regex( ['img'] ) . '/', $content, $matches, PREG_SET_ORDER ); | |
// See 'sub matches' for get_shortcode_regex in /wp-includes/shortcodes.php | |
if ( empty( $matches ) ) | |
return $content; | |
foreach ( $matches as $shortcode ) { | |
$attrs = shortcode_parse_atts( $shortcode[3] ); | |
$attr_img_string = ''; | |
$attr_link_string = ''; | |
// Setup Image Classes as WP Editor Attributes | |
$classes_arr = !empty( $attrs['class'] ) ? explode( ' ', $attrs['class'] ) : []; | |
if( !empty( $attrs['attachment'] ) ) { | |
// Pass Attachment ID to WP Editor | |
$wp_id = 'wp-image-' . intval( $attrs['attachment'] ); | |
if( false === array_search( $wp_id, $classes_arr ) ) | |
$classes_arr[] = $wp_id; | |
// Pass Size to WP Editor | |
$wp_size = 'size-' . $attrs['size']; | |
if( false === array_search( $wp_size, $classes_arr ) ) | |
$classes_arr[] = $wp_size; | |
// Pass Link to WP Editor | |
if( !empty( $attrs['linkto'] ) ) { | |
if ( 'file' === $attrs['linkto'] ) { | |
$attrs['url'] = wp_get_attachment_url( $attrs['attachment'] ); | |
} elseif ( 'post' === $attrs['linkto'] ) { | |
$attrs['url'] = get_attachment_link( $attrs['attachment'] ); | |
} | |
} | |
} | |
// Pass align to WP Editor | |
if( !empty( $attrs['align'] ) ) { | |
$wp_align = 'align' . $attrs['align']; | |
if( false === array_search( $wp_align, $classes_arr ) ) | |
$classes_arr[] = $wp_align; | |
// Remove Shortcode Attribute | |
unset( $attrs['align'] ); | |
} | |
// Remove Shortcode Attributes | |
unset( $attrs['attachment'] ); | |
unset( $attrs['size'] ); | |
unset( $attrs['linkto'] ); | |
$attrs['class'] = trim( implode( ' ', $classes_arr ) ); | |
// list to string: | |
foreach( $attrs as $name => $value) { | |
if( 'url' === $name ) { | |
$attr_link_string .= ' href="' . $value . '"'; | |
continue; | |
} elseif( false !== strpos( $name, 'link_' ) ) { | |
$name = str_replace( 'link_', '', $name ); | |
$attr_link_string .= sprintf( ' %s="%s"', $name, $value ); | |
continue; | |
} | |
$attr_img_string .= sprintf( ' %s="%s"', $name, $value ); | |
} | |
$html = '<img' . $attr_img_string . '>'; | |
if( ! empty( $attr_link_string ) ) { | |
$html = '<a' . $attr_link_string . '>' . $html . '</a>'; | |
} | |
// Replace the shortcode: | |
$content = str_replace( $shortcode[0], $html, $content ); | |
} | |
return $content; | |
} | |
add_filter( 'content_edit_pre', __NAMESPACE__ . '\\shortcode2html' ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* Get an attachment ID given a URL. | |
* @param string $url | |
* @return array( ['id'], ['size'] ) | |
*/ | |
function get_attachment_id( $url ) { | |
$attachment = []; | |
$uploads = wp_upload_dir(); | |
// Search Uploads URL. Return as $mat[1] | |
if ( preg_match( '|^' . preg_quote( $uploads['baseurl'] ) . '(.*)$|i', $url, $mat ) ) { | |
$file = pathinfo( $mat[1] ); | |
$query = get_posts( [ 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'posts_per_page' => '-1' ] ); | |
// exit if attachment posts not found( | |
if( empty( $query ) ) return; | |
foreach( $query as $post ) { | |
// Get all file data | |
$image_meta = get_post_meta( $post->ID, '_wp_attachment_metadata', true ); | |
// 1. Check File URL. | |
if( false === strpos( $image_meta['file'], ltrim( $file['dirname'], '/' ) ) ) | |
continue; | |
// Check match the base file | |
if( $file['basename'] === basename( $image_meta['file'] ) ) { | |
// 2. URL verified. Filename verified. Win! | |
$attachment['id'] = $post->ID; | |
$attachment['size'] = 'file'; | |
// We are win! | |
break; | |
} | |
// Search matching available sizes | |
foreach( $image_meta['sizes'] as $key => $value ) { | |
if( $file['basename'] === basename( $value['file'] ) ) { | |
// 3. URL verified. Filename verified. Win! | |
$attachment['id'] = $post->ID; | |
$attachment['size'] = $key; | |
// We are win! | |
break 2; | |
} | |
} | |
} | |
} | |
return $attachment; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment