PrestaShop: allow customers to upload PDF, AI and EPS files as product customization

懵懂的女人 提交于 2019-12-24 01:05:24

问题


I am running Prestashop 1.6.1.7 and I have the following pictureUpload() method that allows users to upload files of their choosing. By default Prestashop allows uploads of GIF, JPG, JPEG or PNG only.

I'm trying to allow users the ability to upload a few more types (pdf, ai and eps specifically)

Here is the pictureUpload() method in the productController override:

protected function pictureUpload()
{
    if (!$field_ids = $this->product->getCustomizationFieldIds()) {
        return false;
    }
    $authorized_file_fields = array();
    foreach ($field_ids as $field_id) {
        if ($field_id['type'] == Product::CUSTOMIZE_FILE) {
            $authorized_file_fields[(int)$field_id['id_customization_field']] = 'file'.(int)$field_id['id_customization_field'];
        }
    }
    $indexes = array_flip($authorized_file_fields);
    foreach ($_FILES as $field_name => $file) {
        if (in_array($field_name, $authorized_file_fields) && isset($file['tmp_name']) && !empty($file['tmp_name'])) {
            //$file_name = md5(uniqid(rand(), true));
            $file_name = $file['name']; // In this

            if ($error = ImageManager::validateUpload($file, (int)Configuration::get('PS_PRODUCT_PICTURE_MAX_SIZE'))) {
                $this->errors[] = $error;
            }

            $product_picture_width = (int)Configuration::get('PS_PRODUCT_PICTURE_WIDTH');
            $product_picture_height = (int)Configuration::get('PS_PRODUCT_PICTURE_HEIGHT');
            $tmp_name = tempnam(_PS_TMP_IMG_DIR_, 'PS');
            if ($error || (!$tmp_name || !move_uploaded_file($file['tmp_name'], $tmp_name))) {
                return false;
            }
            /* Original file */
            if (!ImageManager::resize($tmp_name, _PS_UPLOAD_DIR_.$file_name)) {
                $this->errors[] = Tools::displayError('An error occurred during the image upload process.');
            }
            /* A smaller one */
            elseif (!ImageManager::resize($tmp_name, _PS_UPLOAD_DIR_.$file_name.'_small', $product_picture_width, $product_picture_height)) {
                $this->errors[] = Tools::displayError('An error occurred during the image upload process.');
            } elseif (!chmod(_PS_UPLOAD_DIR_.$file_name, 0777) || !chmod(_PS_UPLOAD_DIR_.$file_name.'_small', 0777)) {
                $this->errors[] = Tools::displayError('An error occurred during the image upload process.');
            } else {
                $this->context->cart->addPictureToProduct($this->product->id, $indexes[$field_name], Product::CUSTOMIZE_FILE, $file_name);
            }
            unlink($tmp_name);
        }
    }
    return true;
}

This is looking to the ImageManager class, which has this method (that I have updated the error message on):

public static function validateUpload($file, $max_file_size = 0, $types = null)
{

    if ((int)$max_file_size > 0 && $file['size'] > (int)$max_file_size) {
        return sprintf(Tools::displayError('Image is too large (%1$d kB). Maximum allowed: %2$d kB'), $file['size'] / 1024, $max_file_size / 1024);
    }
    if (!ImageManager::isRealImage($file['tmp_name'], $file['type']) || !ImageManager::isCorrectImageFileExt($file['name'], $types) || preg_match('/\%00/', $file['name'])) {
        return Tools::displayError('Image format not recognized, allowed formats are: .gif, .jpg, .png, .pdf, .ai, .eps'); //I Updated This - this is the error kicking off when I try to upload AI
    }
    if ($file['error']) {
        return sprintf(Tools::displayError('Error while uploading image; please change your server\'s settings. (Error code: %s)'), $file['error']);
    }
    return false;
}

The place where that method fails is pointing to two additional methods posted below. I updated the isRealImage method to try and allow the types I wanted through, but it still fails (and I commented where it fails).

public static function isRealImage($filename, $file_mime_type = null, $mime_type_list = null)
{
    // Detect mime content type
    $mime_type = false;
    if (!$mime_type_list) {
        //I UPDATED THIS LIST TO ALLOW FOR OTHER FILETYPES
        $mime_type_list = array('image/gif', 'image/jpg', 'image/jpeg', 'image/pjpeg', 'image/png', 'image/x-png', 'application/illustrator', 'application/ai', 'application/eps', 'application/x-eps', 'image/eps', 'image/x-eps', 'application/pdf', 'application/acrobat', 'application/x-pdf', 'text/pdf', 'text/x-pdf');
    }

    // Try 4 different methods to determine the mime type

    if (function_exists('getimagesize')) {
        $image_info = @getimagesize($filename);
        //HERE IMAGE_INFO IS SHOWING AS 'FALSE' SO IT GOES NO FURTHER WHEN UPLOADING A .AI FILE
        if ($image_info) {
            $mime_type = $image_info['mime'];
        } else {
            $file_mime_type = false;
        }
    } elseif (function_exists('finfo_open')) {
        $const = defined('FILEINFO_MIME_TYPE') ? FILEINFO_MIME_TYPE : FILEINFO_MIME;
        $finfo = finfo_open($const);
        $mime_type = finfo_file($finfo, $filename);
        finfo_close($finfo);
    } elseif (function_exists('mime_content_type')) {
        $mime_type = mime_content_type($filename);
    } elseif (function_exists('exec')) {
        $mime_type = trim(exec('file -b --mime-type '.escapeshellarg($filename)));
        if (!$mime_type) {
            $mime_type = trim(exec('file --mime '.escapeshellarg($filename)));
        }
        if (!$mime_type) {
            $mime_type = trim(exec('file -bi '.escapeshellarg($filename)));
        }
    }

    if ($file_mime_type && (empty($mime_type) || $mime_type == 'regular file' || $mime_type == 'text/plain')) {
        $mime_type = $file_mime_type;
    }

    // For each allowed MIME type, we are looking for it inside the current MIME type
    foreach ($mime_type_list as $type) {
        if (strstr($mime_type, $type)) {
            return true;
        }
    }

    return false;
}

I also updated the isCorrectImageFileExt method:

public static function isCorrectImageFileExt($filename, $authorized_extensions = null)
{
    // Filter on file extension
    if ($authorized_extensions === null) {
        //ADDED ALLOWED TYPES I WANT
        $authorized_extensions = array('gif', 'jpg', 'jpeg', 'jpe', 'png', 'pdf', 'ai', 'eps');
    }
    $name_explode = explode('.', $filename);
    if (count($name_explode) >= 2) {
        $current_extension = strtolower($name_explode[count($name_explode) - 1]);
        if (!in_array($current_extension, $authorized_extensions)) {
            return false;
        }
    } else {
        return false;
    }

    return true;
}

Thoughts on this?

Help on this?


回答1:


You have gone too deep :). This is the pictureUpload method of ProductController that I've already made, you don't need others overrides. With my override you can upload pdf, ai, cdr and eps, but obviously you can change with your needs.

protected function pictureUpload()
{
    if (!$field_ids = $this->product->getCustomizationFieldIds()) {
        return false;
    }
    $authorized_file_fields = array();
    foreach ($field_ids as $field_id) {
        if ($field_id['type'] == Product::CUSTOMIZE_FILE) {
            $authorized_file_fields[(int)$field_id['id_customization_field']] = 'file'.(int)$field_id['id_customization_field'];
        }
    }
    $indexes = array_flip($authorized_file_fields);

    foreach ($_FILES as $field_name => $file) {
        if (in_array($field_name, $authorized_file_fields) && isset($file['tmp_name']) && !empty($file['tmp_name'])) {
            $file_name = md5(uniqid(rand(), true));

            // Bad check, but rapid
            $extension = substr($file['name'], -3, 3);
            if($extension == 'jpg' OR $extension == 'gif' OR $extension == 'png'){
                if ($error = ImageManager::validateUpload($file, (int)Configuration::get('PS_PRODUCT_PICTURE_MAX_SIZE'))) {
                    $this->errors[] = $error;
                }

                $product_picture_width = (int)Configuration::get('PS_PRODUCT_PICTURE_WIDTH');
                $product_picture_height = (int)Configuration::get('PS_PRODUCT_PICTURE_HEIGHT');
                $tmp_name = tempnam(_PS_TMP_IMG_DIR_, 'PS');
                if ($error || (!$tmp_name || !move_uploaded_file($file['tmp_name'], $tmp_name))) {
                    return false;
                }
                /* Original file */
                if (!ImageManager::resize($tmp_name, _PS_UPLOAD_DIR_.$file_name)) {
                    $this->errors[] = Tools::displayError('An error occurred during the image upload process.');
                }
                /* A smaller one */
                elseif (!ImageManager::resize($tmp_name, _PS_UPLOAD_DIR_.$file_name.'_small', $product_picture_width, $product_picture_height)) {
                    $this->errors[] = Tools::displayError('An error occurred during the image upload process.');
                } elseif (!chmod(_PS_UPLOAD_DIR_.$file_name, 0777) || !chmod(_PS_UPLOAD_DIR_.$file_name.'_small', 0777)) {
                    $this->errors[] = Tools::displayError('An error occurred during the image upload process.');
                } else {
                    $this->context->cart->addPictureToProduct($this->product->id, $indexes[$field_name], Product::CUSTOMIZE_FILE, $file_name);
                }
                unlink($tmp_name);
            } elseif ($extension == 'pdf' OR $extension == '.ai' OR $extension == 'cdr' OR $extension == 'eps') {
                $file_name = $file_name.'.'.str_replace('.', '', $extension);
                if (!move_uploaded_file($file['tmp_name'], _PS_UPLOAD_DIR_.$file_name)) {
                    return false;
                }
                chmod(_PS_UPLOAD_DIR_.$file_name, 0777);
                $this->context->cart->addPictureToProduct($this->product->id, $indexes[$field_name], Product::CUSTOMIZE_FILE, $file_name);
            } else {
                $this->errors[] = Tools::displayError('This format is not accepted');
            }
        }
    }
    return true;
}

After that you have to customize product.tpl, the cart summary of your template, and the backoffice order detail :)



来源:https://stackoverflow.com/questions/39925327/prestashop-allow-customers-to-upload-pdf-ai-and-eps-files-as-product-customiza

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!