Last active
January 17, 2024 14:03
-
-
Save nikkyandrei/c6cbc51fd1ab42185fc703a148d7b7ab to your computer and use it in GitHub Desktop.
woocomerce_rest_api_upload_image_base64.php
This file contains hidden or 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 | |
// this is only a part of it | |
namespace DLS_WC_REST; | |
class Products extends \WC_REST_Products_Controller { | |
protected $namespace = 'wc/v3'; | |
public function register_routes() { | |
// To DO: to see if in this version works withouth | |
parent::register_routes(); | |
register_rest_route( | |
$this->namespace, | |
'/' . $this->rest_base . '/product-apk', | |
array( | |
array( | |
'methods' => \WP_REST_Server::CREATABLE, | |
'callback' => array($this, 'dls_create_item'), | |
'permission_callback' => array($this, 'create_item_permissions_check'), | |
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::CREATABLE), | |
), | |
'schema' => array($this, 'get_public_item_schema'), | |
) | |
); | |
} | |
public function dls_create_item($request) { | |
if (!empty($request['id'])) { | |
return new \WP_Error("woocommerce_rest_{$this->post_type}_exists", sprintf(__('Cannot create existing %s.', 'woocommerce'), $this->post_type), array('status' => 400)); | |
} | |
$param = $request->get_params(); | |
if (isset($param['images'])) { | |
$new_images = []; | |
foreach ($param['images'] as $img) { | |
$img['src'] = explode("//", $img['src']); | |
$img['src'] = $img['src'][1]; | |
$decoded = ""; | |
// decode large images | |
for ($i = 0; $i < ceil(strlen($img['src']) / 256); $i++) | |
$decoded = $decoded . base64_decode(substr($img['src'], $i * 256, 256)); | |
if (strpos($decoded, ';base64,') !== false) { | |
$options = get_option('dls_android_intern_options'); | |
$sizes = []; | |
$sizes['dpi'] = $options['dpi']; | |
$sizes['width'] = $options['width']; | |
$sizes['height'] = $options['height']; | |
if ($options['crop_horizontal']) { | |
$sizes['crop'] = [$options['crop_horizontal'], $options['crop_vertical']]; | |
} else { | |
$sizes['crop'] = false; | |
} | |
$new_images[] = ['id' => $this->uploadImage($decoded, $param['name'], $sizes)]; | |
} | |
} | |
} | |
$request->set_param('images', $new_images); | |
// make sure i don't make custom attributes for already created ones | |
if (isset($param['attributes'])) { | |
foreach ($param['attributes'] as $k => $att) { | |
$att_id = wc_attribute_taxonomy_id_by_name($att['name']); | |
if ($att_id) { | |
$param['attributes'][$k]['id'] = $att_id; | |
unset($param['attributes'][$k]['name']); | |
} | |
} | |
} | |
$request->set_param('attributes', $param['attributes']); | |
$this->create_item($reques); | |
} | |
public 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 crop = false, true , [center|left|right,center|top|bottom ] : | |
// 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/ | |
// 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 = wp_get_default_extension_for_mime_type($mime_type); | |
if (!$ext) { | |
return false; | |
} | |
// Upload dir. | |
$upload_dir = wp_upload_dir(); | |
$upload_path = str_replace('/', DIRECTORY_SEPARATOR, $upload_dir['path']) . DIRECTORY_SEPARATOR; | |
//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_dir['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 . DIRECTORY_SEPARATOR . $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 | |
$this->setImageDpi($the_file, $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_dir['url'] . '/' . $filename | |
); | |
$attach_id = wp_insert_attachment($attachment, $upload_dir['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, trailingslashit($upload_dir['path']) . $filename); | |
wp_update_attachment_metadata($attach_id, $attach_data); | |
return $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; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment