Skip to content

Instantly share code, notes, and snippets.

@nikkyandrei
Last active January 17, 2024 14:03
Show Gist options
  • Save nikkyandrei/c6cbc51fd1ab42185fc703a148d7b7ab to your computer and use it in GitHub Desktop.
Save nikkyandrei/c6cbc51fd1ab42185fc703a148d7b7ab to your computer and use it in GitHub Desktop.
woocomerce_rest_api_upload_image_base64.php
<?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