html_string = str_replace( '\"' , '' , $html_string);
}
/**
* Extract all html needed info from text
*/
public function parse(){
if( trim($this->html_string) == '' ){
return false;
}
$doc = new DOMDocument('1.0', 'UTF-8');
libxml_use_internal_errors(true);
$doc->loadHTML(
mb_convert_encoding($this->html_string, 'HTML-ENTITIES', 'UTF-8'),
(defined('LIBXML_HTML_NOIMPLIED') ? LIBXML_HTML_NOIMPLIED : 0) | (defined('LIBXML_HTML_NODEFDTD') ? LIBXML_HTML_NODEFDTD : 0)
);
// find all img tags
$elementImg = $doc->getElementsByTagName('img');
$elementImgSrc = [];
foreach ($elementImg as $index => $value){
$alt = $value->getAttribute('alt');
// Replace dangerous double quotes inside alt with safe quotes
$fixedAlt = str_replace(['"', '\'', '\\'], ['«', ' ', ' '], $alt);
$value->setAttribute('alt', $fixedAlt);
$raw_base64_src = str_replace('\"' , '' , $value->getAttribute('src'));
//upload image on server instead of using base64 url
$uploaded_url = $this->uploadImageWithFallback($raw_base64_src, "rp-img-".wp_rand(1 , 100000));
if( !$uploaded_url ){
// remove image
$value->parentNode->removeChild($value);
continue;
}
else {
$value->setAttribute('src' , $uploaded_url);
$elementImgSrc[] = [ 'src' => $uploaded_url, 'alt' => $fixedAlt];
}
}
$lengthImg = count($elementImgSrc);
// find all H1 tags
$elementH1= $doc->getElementsByTagName('h1');
foreach ($elementH1 as $index => $value){
// remove H1
$parentNode = $value->parentNode;
$parentNode->removeChild($value);
}
$elementH2= $doc->getElementsByTagName('h2');
$elementArrayH2 = [];
foreach ($elementH2 as $index => $value){
if( $value->firstChild->tagName == 'img' ){
$alt = $value->firstChild->getAttribute('alt');
// Replace dangerous double quotes inside alt with safe quotes
$fixedAlt = str_replace(['"', '\'', '\\'], ['«', ' ', ' '], $alt);
$value->firstChild->setAttribute('alt', $fixedAlt);
$raw_base64_src = str_replace('\"' , '' , $value->firstChild->getAttribute('src'));
// upload image on server instead of using base64 url
$uploaded_url = $this->uploadImageWithFallback($raw_base64_src, "rp-img-".wp_rand(1 , 100000));
if ( !$uploaded_url ) {
// remove image if we still can't upload it
$parentNode = $value->parentNode;
$parentNode->removeChild($value);
continue;
}
$value->firstChild->setAttribute('src' , $uploaded_url);
$elementImgSrc[] = [ 'src' => $uploaded_url, 'alt' => $fixedAlt ];
// make image centered!
$value->firstChild->setAttribute('style' , 'margin: auto;display: block;border-radius: 20px;max-width: 100%');
$value->firstChild->setAttribute('width' , "100%");
// save this image at this location in html
$snippetH2 .= $value->firstChild->ownerDocument->saveHTML($value->firstChild);
$elementArrayH2[] = $snippetH2;
continue;
}
else {
// if H2 is Not Empty
if( trim($value->nodeValue) !== "" ){
$elementArrayH2[] = $value->nodeValue;
$snippetH2 .= $value->nodeValue;
}
else {
// remove empty H2
$parentNode = $value->parentNode;
$parentNode->removeChild($value);
}
}
}
$lengthH2 = count($elementArrayH2);
$explodeH2 = explode(' ' ,$snippetH2);
$explodeCountH2 = count($explodeH2);
$elementH3= $doc->getElementsByTagName('h3');
$elementArrayH3 = [];
foreach ($elementH3 as $index => $value){
if( $value->firstChild->tagName == 'img' ){
$alt = $value->firstChild->getAttribute('alt');
// Replace dangerous double quotes inside alt with safe quotes
$fixedAlt = str_replace(['"', '\'', '\\'], ['«', ' ', ' '], $alt);
$value->firstChild->setAttribute('alt', $fixedAlt);
$raw_base64_src = str_replace('\"' , '' , $value->firstChild->getAttribute('src'));
// upload image on server instead of using base64 url
$uploaded_url = $this->uploadImageWithFallback($raw_base64_src, "rp-img-".wp_rand(1 , 100000));
if ( !$uploaded_url ) {
// remove image if we still can't upload it
$parentNode = $value->parentNode;
$parentNode->removeChild($value);
continue;
}
$value->firstChild->setAttribute('src' , $uploaded_url);
$elementImgSrc[] = [ 'src' => $uploaded_url, 'alt' => $fixedAlt ];
// make image centered!
$value->firstChild->setAttribute('style' , 'margin: auto;display: block;border-radius: 20px;max-width: 100%');
$value->firstChild->setAttribute('width' , "100%");
// save this image at this location in html
$snippetH3 .= $value->firstChild->ownerDocument->saveHTML($value->firstChild);
$elementArrayH3[] = $snippetH3;
continue;
}
else {
// if H3 is Not Empty
if( trim($value->nodeValue) !== "" ){
$elementArrayH3[] = $value->nodeValue;
$snippetH3 .= $value->nodeValue;
}
else {
// remove empty H3
$parentNode = $value->parentNode;
$parentNode->removeChild($value);
}
}
}
$lengthH3 = count($elementArrayH3);
$explodeH3 = explode(' ' ,$snippetH3);
$explodeCountH3 = count($explodeH3);
$elementH4= $doc->getElementsByTagName('h4');
$elementArrayH4 = [];
foreach ($elementH4 as $index => $value){
if( $value->firstChild->tagName == 'img' ){
$alt = $value->firstChild->getAttribute('alt');
// Replace dangerous double quotes inside alt with safe quotes
$fixedAlt = str_replace(['"', '\'', '\\'], ['«', ' ', ' '], $alt);
$value->firstChild->setAttribute('alt', $fixedAlt);
$raw_base64_src = str_replace('\"' , '' , $value->firstChild->getAttribute('src'));
// upload image on server instead of using base64 url
$uploaded_url = $this->uploadImageWithFallback($raw_base64_src, "rp-img-".wp_rand(1 , 100000));
if ( !$uploaded_url ) {
// remove image if we still can't upload it
$parentNode = $value->parentNode;
$parentNode->removeChild($value);
continue;
}
$value->firstChild->setAttribute('src' , $uploaded_url);
$elementImgSrc[] = [ 'src' => $uploaded_url, 'alt' => $fixedAlt ];
// make image centered!
$value->firstChild->setAttribute('style' , 'margin: auto;display: block;border-radius: 20px;max-width: 100%');
$value->firstChild->setAttribute('width' , "100%");
// save this image at this location in html
$snippetH4 .= $value->firstChild->ownerDocument->saveHTML($value->firstChild);
$elementArrayH4[] = $snippetH4;
continue;
}
else {
// if H4 is Not Empty
if( trim($value->nodeValue) !== "" ){
$elementArrayH4[] = $value->nodeValue;
$snippetH4 .= $value->nodeValue;
}
else {
// remove empty H4
$parentNode = $value->parentNode;
$parentNode->removeChild($value);
}
}
}
$lengthH4 = count($elementArrayH4);
$explodeH4 = explode(' ' ,$snippetH4);
$explodeCountH4 = count($explodeH4);
$elementH5= $doc->getElementsByTagName('h5');
$elementArrayH5 = [];
foreach ($elementH5 as $index => $value){
if( $value->firstChild->tagName == 'img' ){
$alt = $value->firstChild->getAttribute('alt');
// Replace dangerous double quotes inside alt with safe quotes
$fixedAlt = str_replace(['"', '\'', '\\'], ['«', ' ', ' '], $alt);
$value->firstChild->setAttribute('alt', $fixedAlt);
$raw_base64_src = str_replace('\"' , '' , $value->firstChild->getAttribute('src'));
// upload image on server instead of using base64 url
$uploaded_url = $this->uploadImageWithFallback($raw_base64_src, "rp-img-".wp_rand(1 , 100000));
if ( !$uploaded_url ) {
// remove image if we still can't upload it
$parentNode = $value->parentNode;
$parentNode->removeChild($value);
continue;
}
$value->firstChild->setAttribute('src' , $uploaded_url);
$elementImgSrc[] = [ 'src' => $uploaded_url, 'alt' => $fixedAlt ];
// save this image at this location in html
$snippetH5 .= $value->firstChild->ownerDocument->saveHTML($value->firstChild);
$elementArrayH5[] = $snippetH5;
continue;
}
else {
// if H5 is Not Empty
if( trim($value->nodeValue) !== "" ){
$elementArrayH5[] = $value->nodeValue;
$snippetH5 .= $value->nodeValue;
}
else {
// remove empty H5
$parentNode = $value->parentNode;
$parentNode->removeChild($value);
}
}
}
$lengthH5 = count($elementArrayH5);
$explodeH5 = explode(' ' ,$snippetH5);
$explodeCountH5 = count($explodeH5);
$elementH6= $doc->getElementsByTagName('h6');
$elementArrayH6 = [];
foreach ($elementH6 as $index => $value){
if( $value->firstChild->tagName == 'img' ){
$alt = $value->firstChild->getAttribute('alt');
// Replace dangerous double quotes inside alt with safe quotes
$fixedAlt = str_replace(['"', '\'', '\\'], ['«', ' ', ' '], $alt);
$value->firstChild->setAttribute('alt', $fixedAlt);
$raw_base64_src = str_replace('\"' , '' , $value->firstChild->getAttribute('src'));
// upload image on server instead of using base64 url
$uploaded_url = $this->uploadImageWithFallback($raw_base64_src, "rp-img-".wp_rand(1 , 100000));
if ( !$uploaded_url ) {
// remove image if we still can't upload it
$parentNode = $value->parentNode;
$parentNode->removeChild($value);
continue;
}
$value->firstChild->setAttribute('src' , $uploaded_url);
$elementImgSrc[] = [ 'src' => $uploaded_url, 'alt' => $fixedAlt ];
// save this image at this location in html
$snippetH6 .= $value->firstChild->ownerDocument->saveHTML($value->firstChild);
$elementArrayH6[] = $snippetH6;
continue;
}
else {
// if H6 is Not Empty
if( trim($value->nodeValue) !== "" ){
$elementArrayH6[] = $value->nodeValue;
$snippetH6 .= $value->nodeValue;
}
else {
// remove empty H6
$parentNode = $value->parentNode;
$parentNode->removeChild($value);
}
}
}
$lengthH6 = count($elementArrayH6);
$explodeH6 = explode(' ' ,$snippetH6);
$explodeCountH6 = count($explodeH6);
// Save only the inner HTML (avoid DOCTYPE/head/body wrappers)
$modifiedHtml = '';
$body = $doc->getElementsByTagName('body')->item(0);
if ($body) {
foreach ($body->childNodes as $child) {
$modifiedHtml .= $doc->saveHTML($child);
}
} else {
$modifiedHtml = $doc->saveHTML();
}
libxml_clear_errors();
libxml_use_internal_errors(false);
$elementAll = (object) [
'elementImg' => array ('count' => $lengthImg , 'items' => $elementImgSrc) ,
'elementH1' => array('count' => $lengthH1 , 'items' => $elementArrayH1) ,
'elementH2' => array('count' => $lengthH2 , 'items' => $elementArrayH2) ,
'elementH3' => array('count' => $lengthH3 , 'items' => $elementArrayH3) ,
'elementH4' => array('count' => $lengthH4 , 'items' => $elementArrayH4) ,
'elementH5' => array('count' => $lengthH5 , 'items' => $elementArrayH5) ,
'elementH6' => array('count' => $lengthH6 , 'items' => $elementArrayH6) ,
'fullContent' => $modifiedHtml,
];
return $elementAll;
}
/**
* Get (and create if needed) the plugin-specific uploads subdirectory.
*
* @return array|false Array with 'path', 'url', 'subdir' keys, or false on failure.
*/
private function get_plugin_upload_dir() {
$upload_dir = wp_upload_dir();
if ( ! empty( $upload_dir['error'] ) ) {
return false;
}
$plugin_subdir = '/autopost';
$path = $upload_dir['basedir'] . $plugin_subdir;
$url = $upload_dir['baseurl'] . $plugin_subdir;
if ( ! is_dir( $path ) ) {
wp_mkdir_p( $path );
}
return array(
'path' => trailingslashit( $path ),
'url' => trailingslashit( $url ),
'subdir' => $plugin_subdir,
);
}
/**
* Upload image to server instead of using Base64
*/
private function uploadImage($base64_img, $title, $max_size = []) {
// option to resize image - will save space on host usualy don't need image more than 1920 x 1080
// read more information on :
// https://developer.wordpress.org/reference/functions/image_resize_dimensions/
// https://developer.wordpress.org/reference/classes/wp_image_editor_imagick/resize/
// or
// https://developer.wordpress.org/reference/classes/wp_image_editor_gd/resize/
// crop = false
// or
// crop[0] = center|left|right
// crop[1] = center|top|bottom
//
// also if one of "width" or "height" = 0 the image will keep ratio
// if "width" and "height" = 0 image will not be croped
$max_size = array_merge([
'width' => 0,
'height' => 0,
'crop' => ['center', 'center'],
'dpi'=>96, // usualy for web is I see 72
], $max_size);
// with fix for data:image/jpeg;charset=utf-8;base64,
// https://en.wikipedia.org/wiki/Data_URI_scheme#Syntax
// generate corect filename as WP
// extract entire data mime type ex data:image/jpeg or data:text/plain
//
$data_src = substr($base64_img, 0, strpos($base64_img, "base64"));
$mime_type = substr($base64_img, 0, strpos($base64_img, ";"));
// extract mime type ex image/jpeg or text/plain
$mime_type = substr($mime_type, 5);
// fix: "data: image"
$mime_type = str_replace(' ', '', $mime_type);
// make sure is image/* I make a limitation on image but you can skip this for other mime_types
if (strpos($mime_type, 'image') === false) {
return false;
}
// return extension if false return
$ext = function_exists('wp_get_default_extension_for_mime_type')
? wp_get_default_extension_for_mime_type($mime_type)
: '';
if (!$ext) {
return false;
}
// Upload dir - use plugin-specific subdirectory.
$plugin_upload = $this->get_plugin_upload_dir();
if ( ! $plugin_upload ) {
return false;
}
$upload_path = $plugin_upload['path'];
$upload_url = $plugin_upload['url'];
//this is optional but you make sure you don't generate Name.jpg and also name.jpg
$title = strtolower($title);
// set file name and make sure is unique tile will be sanitized by WP
$filename = $title . '.' . $ext;
$filename = wp_unique_filename($upload_path, $filename, null);
// get image content and decode it
$img_content = str_replace($data_src . 'base64,', '', $base64_img);
$img_content = str_replace(' ', '+', $img_content);
// decode in chunks for large images fix
$decoded = "";
for ($i = 0; $i < ceil(strlen($img_content) / 256); $i++) {
$decoded = $decoded . base64_decode(substr($img_content, $i * 256, 256));
}
$img_content = $decoded;
$the_file = $upload_path . $filename;
// Save the image in the uploads directory.
file_put_contents($the_file, $img_content);
// set max DPI for jpg, png, gif, webp before any resize
//setImageDpi($the_file, count($max_size) != 0 ? $max_size['dpi'] : '');
// resize image
if (!empty($max_size['width']) || !empty($max_size['height'])) {
$image = wp_get_image_editor($the_file); // Return an implementation that extends WP_Image_Editor
if (!is_wp_error($image)) {
$image->resize((int) $max_size['width'], (int) $max_size['height'], $max_size['crop']);
$image->save($the_file);
}
}
$attachment = array(
'post_mime_type' => $mime_type,
'post_title' => preg_replace('/\.[^.]+$/', '', $filename),
'post_content' => '',
'post_status' => 'inherit',
'guid' => $upload_url . $filename
);
$attach_id = wp_insert_attachment($attachment, $upload_path . $filename);
// make sure function wp_generate_attachment_metadata exist
if (!function_exists('wp_generate_attachment_metadata')) {
require_once( ABSPATH . 'wp-admin/includes/image.php' );
}
$attach_data = wp_generate_attachment_metadata($attach_id, $upload_path . $filename);
wp_update_attachment_metadata($attach_id, $attach_data);
return wp_get_attachment_url($attach_id);
}
/**
* Try main upload method, then fallback if it fails.
*
* This wrapper makes sure images are uploaded as reliably as possible
* across different WordPress / hosting environments.
*/
private function uploadImageWithFallback($base64_img, $title, $max_size = []) {
// First, try the primary method.
$uploaded_url = $this->uploadImage($base64_img, $title, $max_size);
if ($uploaded_url && is_string($uploaded_url)) {
return $uploaded_url;
}
// If that failed, try a more permissive fallback uploader.
$fallback_url = $this->uploadImageFallback($base64_img, $title, $max_size);
if ($fallback_url && is_string($fallback_url)) {
return $fallback_url;
}
return false;
}
/**
* Fallback image upload that avoids strict MIME / extension detection
* and works on a wider range of WordPress / PHP setups.
*/
private function uploadImageFallback($base64_img, $title, $max_size = []) {
// Ensure we have sane defaults for resize options, similar to main method.
$max_size = array_merge([
'width' => 0,
'height' => 0,
'crop' => ['center', 'center'],
'dpi' => 96,
], $max_size);
// Decode base64 payload in a simpler / more tolerant way.
if (strpos($base64_img, 'base64,') !== false) {
$img_content = substr($base64_img, strpos($base64_img, 'base64,') + 7);
} else {
// Assume the whole string is base64 without a data URI prefix.
$img_content = $base64_img;
}
$img_content = str_replace(' ', '+', $img_content);
$binary = base64_decode($img_content);
if (!$binary) {
return false;
}
// Use PHP to detect image mime type directly from binary string.
$image_info = @getimagesizefromstring($binary);
if ($image_info === false || empty($image_info['mime']) || strpos($image_info['mime'], 'image/') !== 0) {
return false;
}
$mime_type = $image_info['mime'];
// Minimal, WordPress-independent mime → extension map.
$ext = 'jpg';
if ($mime_type === 'image/png') {
$ext = 'png';
} elseif ($mime_type === 'image/gif') {
$ext = 'gif';
} elseif ($mime_type === 'image/webp') {
$ext = 'webp';
}
// Upload dir - use plugin-specific subdirectory.
$plugin_upload = $this->get_plugin_upload_dir();
if ( ! $plugin_upload ) {
return false;
}
$upload_path = $plugin_upload['path'];
$upload_url = $plugin_upload['url'];
// This is optional but makes sure you don't generate Name.jpg and also name.jpg
$title = strtolower($title);
// Set file name and make sure it is unique; title will be sanitized by WP.
$filename = $title . '.' . $ext;
$filename = wp_unique_filename($upload_path, $filename, null);
$the_file = $upload_path . $filename;
// Save the image in the uploads directory.
file_put_contents($the_file, $binary);
if (!file_exists($the_file)) {
return false;
}
// Resize image if requested.
if (!empty($max_size['width']) || !empty($max_size['height'])) {
$image = wp_get_image_editor($the_file);
if (!is_wp_error($image)) {
$image->resize((int) $max_size['width'], (int) $max_size['height'], $max_size['crop']);
$image->save($the_file);
}
}
$attachment = array(
'post_mime_type' => $mime_type,
'post_title' => preg_replace('/\.[^.]+$/', '', $filename),
'post_content' => '',
'post_status' => 'inherit',
'guid' => $upload_url . $filename,
);
$attach_id = wp_insert_attachment($attachment, $upload_path . $filename);
// make sure function wp_generate_attachment_metadata exist
if (!function_exists('wp_generate_attachment_metadata')) {
require_once(ABSPATH . 'wp-admin/includes/image.php');
}
$attach_data = wp_generate_attachment_metadata($attach_id, $upload_path . $filename);
wp_update_attachment_metadata($attach_id, $attach_data);
return wp_get_attachment_url($attach_id);
}
private function setImageDpi($file, $dpi) {
$orig = getimagesize($file);
switch ($orig[2]) {
case 1:
$src = imagecreatefromgif($file);
break;
case 2:
$src = imagecreatefromjpeg($file);
break;
case 3:
$src = imagecreatefrompng($file);
break;
case 18:
$src = imagecreatefromwebp($file);
break;
default:
return '';
break;
}
if (empty($src))
return'';
$res=imageresolution($src);
$res[0]= min($res[0],$dpi);
$res[1]= min($res[1],$dpi);
imageresolution($src, $res[0], $res[1]);
switch ($orig[2]) {
case 1:
$src = imagegif($src, $file);
break;
case 2:
$src = imagejpeg($src, $file);
break;
case 3:
$src = imagepng($src, $file);
break;
case 18:
$src = imagewebp($src, $file);
break;
default:
return '';
break;
}
}
}