147 lines
3.6 KiB
PHP
147 lines
3.6 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Class WPML_Media_Img_Parse
|
|
*/
|
|
class WPML_Media_Img_Parse {
|
|
|
|
/**
|
|
* @param string $text
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_imgs( $text ) {
|
|
$images = $this->get_from_img_tags( $text );
|
|
|
|
if ( $this->can_parse_blocks( $text ) ) {
|
|
$blocks = parse_blocks( $text );
|
|
$images = array_merge( $images, $this->get_from_css_background_images_in_blocks( $blocks ) );
|
|
} else {
|
|
$images = array_merge( $images, $this->get_from_css_background_images( $text ) );
|
|
}
|
|
|
|
return $images;
|
|
}
|
|
|
|
/**
|
|
* @param string $text
|
|
*
|
|
* @return array
|
|
*/
|
|
private function get_from_img_tags( $text ) {
|
|
$images = array();
|
|
|
|
if ( preg_match_all( '/<img ([^>]+)>/s', $text, $matches ) ) {
|
|
foreach ( $matches[1] as $i => $match ) {
|
|
if ( preg_match_all( '/(\S+)\\s*=\\s*["\']?((?:.(?!["\']?\s+(?:\S+)=|[>"\']))+.)["\']?/', $match, $attribute_matches ) ) {
|
|
$attributes = array();
|
|
foreach ( $attribute_matches[1] as $k => $key ) {
|
|
$attributes[ $key ] = $attribute_matches[2][ $k ];
|
|
}
|
|
if ( isset( $attributes['src'] ) ) {
|
|
$images[ $i ]['attributes'] = $attributes;
|
|
$images[ $i ]['attachment_id'] = $this->get_attachment_id_from_attributes( $images[ $i ]['attributes'] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $images;
|
|
}
|
|
|
|
/**
|
|
* @param string $text
|
|
*
|
|
* @return array
|
|
*/
|
|
private function get_from_css_background_images( $text ) {
|
|
$images = array();
|
|
|
|
if ( preg_match_all( '/<\w+[^>]+style\s?=\s?"[^"]*?background-image:url\(\s?([^\s\)]+)\s?\)/', $text, $matches ) ) {
|
|
foreach ( $matches[1] as $src ) {
|
|
$images[] = array(
|
|
'attributes' => array( 'src' => $src ),
|
|
'attachment_id' => null,
|
|
);
|
|
}
|
|
}
|
|
|
|
return $images;
|
|
}
|
|
|
|
/**
|
|
* @param array $blocks
|
|
*
|
|
* @return array
|
|
*/
|
|
private function get_from_css_background_images_in_blocks( $blocks ) {
|
|
$images = array();
|
|
|
|
foreach ( $blocks as $block ) {
|
|
$block = $this->sanitize_block( $block );
|
|
|
|
if ( ! empty( $block->innerBlocks ) ) {
|
|
$inner_images = $this->get_from_css_background_images_in_blocks( $block->innerBlocks );
|
|
$images = array_merge( $images, $inner_images );
|
|
continue;
|
|
}
|
|
|
|
if ( ! isset( $block->innerHTML, $block->attrs->id ) ) {
|
|
continue;
|
|
}
|
|
|
|
$background_images = $this->get_from_css_background_images( $block->innerHTML );
|
|
$image = reset( $background_images );
|
|
|
|
if ( $image ) {
|
|
$image['attachment_id'] = $block->attrs->id;
|
|
$images[] = $image;
|
|
}
|
|
}
|
|
|
|
return $images;
|
|
}
|
|
|
|
/**
|
|
* `parse_blocks` does not specify which kind of collection it should return
|
|
* (not always an array of `WP_Block_Parser_Block`) and the block parser can be filtered,
|
|
* so we'll cast it to a standard object for now.
|
|
*
|
|
* @param mixed $block
|
|
*
|
|
* @return stdClass|WP_Block_Parser_Block
|
|
*/
|
|
private function sanitize_block( $block ) {
|
|
$block = (object) $block;
|
|
|
|
if ( isset( $block->attrs ) ) {
|
|
/** Sometimes `$block->attrs` is an object or an array, so we'll use an object */
|
|
$block->attrs = (object) $block->attrs;
|
|
}
|
|
|
|
return $block;
|
|
}
|
|
|
|
function can_parse_blocks( $string ) {
|
|
return false !== strpos( $string, '<!-- wp:' ) && function_exists( 'parse_blocks' );
|
|
}
|
|
|
|
/**
|
|
* @param $attributes
|
|
*
|
|
* @return null|int
|
|
*/
|
|
private function get_attachment_id_from_attributes( $attributes ) {
|
|
$attachment_id = null;
|
|
if ( isset( $attributes['class'] ) ) {
|
|
if ( preg_match( '/wp-image-([0-9]+)\b/', $attributes['class'], $id_match ) ) {
|
|
if ( 'attachment' === get_post_type( (int) $id_match[1] ) ) {
|
|
$attachment_id = (int) $id_match[1];
|
|
}
|
|
}
|
|
}
|
|
return $attachment_id;
|
|
}
|
|
|
|
}
|