dth2331 2016-10-07 20:29
浏览 90
已采纳

PrestaShop:允许客户上传PDF,AI和EPS文件作为产品定制

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条回答 默认 最新

  • douzhun8615 2016-10-08 08:52
    关注

    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 :)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥30 BC260Y用MQTT向阿里云发布主题消息一直错误
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM
  • ¥15 划分vlan后不通了
  • ¥20 用雷电模拟器安装百达屋apk一直闪退