Principais respostas a perguntas sobre o módulo de personalização de produtos PrestaShop

Posted On: Sep 14, 2018
Categories: Shopping Carts & Platforms
No momento em que há uma grande competição no mercado, apenas os bem-sucedidos são aqueles que adotaram as últimas tendências e técnicas do negócio. Os donos de lojas que mais facilitam os clientes durante a compra têm mais probabilidade de serem bem-sucedidos. A última tendência seguida por donos de lojas bem versados é permitir que o cliente personalize os atributos dos produtos por conta própria, por exemplo, se o cliente estiver comprando uma camisa, ele pode inserir um logotipo nela, escrever algo, colar uma imagem ou qualquer estilo de design na camisa. Tudo será feito pelos clientes e quando toda a personalização for feita, ele pode enviá-la ao administrador na mesma página do produto. Como resultado, a mesma coisa será entregue aos clientes. Como os clientes obtêm controle total sobre seus produtos, eles gostam de ir a essa loja.
Quando entramos na implementação, o PrestaShop em si não é tão flexível. Aqui não podemos dizer que os desenvolvedores do PrestaShop não conhecem essa função. Eles a conhecem muito bem, mas para tornar o software realmente leve, eles estão fornecendo apenas a função necessária em sua instalação. Portanto, é necessário projetar seu próprio módulo para essa finalidade ou usar um módulo de design personalizado PrestaShop gratuito ou pago.
Aqui neste guia, estamos discutindo alguns problemas básicos relacionados à personalização de produtos PrestaShop. Espero que esta postagem de resposta de pergunta ajude muito você a resolver os problemas da loja. Então, vamos começar aqui;
Pergunta nº 1: Olá, estou enfrentando um problema com o campo de personalização do PrestaShop. Quando os clientes carregam um arquivo de imagem, salva e atualiza a página. Ele mostra uma miniatura corrompida. Além disso, quando clico na imagem ou a abro em uma nova guia, ele vai para a página de erro 404. Qual é o problema?
Resposta: Você tem que editar o arquivo /upload/.htaccess e remover a linha php_flag engine off. Você encontrará essas linhas no final do arquivo. Salve o arquivo e ele funcionará bem.
Pergunta nº 2: Olá, quero fazer upload de um arquivo PDF na página de personalização do produto. Atualmente, só consigo fazer upload de arquivos de imagem. Qual ajuste preciso para isso?
Resposta: Para habilitar essa função na sua loja, você tem que substituir o método de upload de imagem do controlador do produto em override>controllers>front
. Baixe o código a seguir, coloque-o em ProductController.php
e carregue-o em override>controllers>front
.
class ProductController extends ProductControllerCore
{
const CUSTOMIZATION_FILE_DIR = 'customizations';
protected function pictureUpload()
{
se (!($field_ids = $this->produto->getCustomizationFieldIds()))
retornar falso;
$authorized_file_fields = array();
foreach ($field_ids AS $field_id)
{
se ($field_id['tipo'] == Produto::CUSTOMIZE_FILE)
$authorized_file_fields[(int)$field_id['id_customization_field']] = 'arquivo' . (int)$field_id['id_customization_field'];
<código> }
<código>
<código> $índices = array_flip($authorized_file_fields);
foreach ($_FILES AS $field_name => $file)
{
se (in_array($field_name, $authorized_file_fields) E isset($file['tmp_name']) E !empty($file['nome_tmp']))
<código>{
// Se houver um erro de upload, deixe o pai lidar com isto
<código> se ($file['error'] != UPLOAD_ERR_OK)
<código> ... continuar;
// Se o arquivo não for permitido, deixe o pai lidar com isto
se (!$this->isUploadTypeAllowed($file))
<código> ...// Desfaça a configuração do PDF para impedir que o pai manipule este arquivo
unset($_FILES[$field_name]);
// Criar diretório
mkdir(_PS_UPLOAD_DIR_ . ProductController::CUSTOMIZATION_FILE_DIR.'/'.$this->context->cart->id, 0777, true);
// Marcar o arquivo como um arquivo personalizado carregar
$file_name = ProductController::CUSTOMIZATION_FILE_DIR.'/'.$this->context->cart->id.'/P'. md5(uniqid(rand(), verdadeiro));
<código> $tmp_name = tempnam(_PS_TMP_IMG_DIR_, 'PS');
se (!move_uploaded_file($file['tmp_name'], $tmp_name))
<código>{
$this->errors[] = Tools::displayError('Ocorreu um erro durante o PDF carregar.');
... falso;
<código>}
// Copiar arquivo para o upload diretório
<código> se (!copiar($tmp_name, _PS_UPLOAD_DIR_.$nome_do_arquivo))
<código>{
$this->errors[] = Tools::displayError('Ocorreu um erro durante o PDF carregar.');
... falso;
<código>}
// Chmod o novo arquivo
<código> se (!chmod(_PS_UPLOAD_DIR_.$nome_do_arquivo, 0777))
<código>{
$this->errors[] = Tools::displayError('Ocorreu um erro durante o PDF carregar.');
... falso;
<código>}
// Crie um polegar falso para evitar erro ao excluir, este hack evita muitos métodos principais substituir
file_put_contents(_PS_UPLOAD_DIR_ . $file_name . '_pequeno', '');
<código> chmod(_PS_UPLOAD_DIR_ . $nome_do_arquivo . '_pequeno', 0777);
// Registre o arquivo
$this->context->cart->addPictureToProduct($this->product->id, $indexes[$field_name], Produto::PERSONALIZAR_ARQUIVO, $file_name);
// Remover tmp arquivo
<código>desvincular($tmp_name);
<código> }
<código>}
retornar pai::pictureUpload();
}
função protegida isUploadTypeAllowed($file)
{
/* Detectar tipo de conteúdo mime */
$mime_type = false;
$types = array('application/pdf',); // Tipos mime extras podem ser adicionados aqui
if (function_exists('finfo_open'))
{
$finfo = finfo_open(FILEINFO_MIME);
$mime_type = finfo_file($finfo, $file['nome_tmp']);
<código> finfo_close($finfo);
<código>}
elseif (function_exists('mime_content_type'))
{
<código> $mime_type = mime_content_type($file['tmp_name']);
<código>}
elseif (function_exists('exec'))
{
<código> $mime_type = trim(exec('file -b --mime-type '.escapeshellarg($file['tmp_name'])));
<código>}
se (vazio($mime_type) || $mime_type == 'arquivo regular')
<código> {
<código> $mime_type = $file['tipo'];
<código> }
<código>
<código> se (($pos = strpos($mime_type, ';')) !== falso)
$mime_type = substr($mime_type, 0, $pos);
// é permitido?
return $mime_type && in_array($mime_type, $types);
}
}
}
Limpe o cache.
se isset($pictures.$key)}
<divclass="customizationUploadBrowse">
{if substr(basename($pictures.$key), 0, 1) == 'P'}
{l s='Visualizar o arquivo'}
{else}
<imgsrc="{$pic_dir}{$pictures.$key}_small"alt=""/>
{/if}
{/if}
Além disso, você precisa corrigir a visualização do arquivo no frontend da loja. Em product.tpl use o seguinte código:{if isset($pictures.$key)}
{if substr(basename($pictures.$key),0,1)=='P'}
{l s='Visualizar o arquivo'}
{else}
{/if}
Abra "order-payment.tpl", "order-detail.tpl", "order-return.tpl" e pesquise por "customizationUploaded", comente o div e cole este código acima dele:
{foreach $custom_data as $imagem}
{se substr(nomebase($imagem.valor), 0, 1) == 'P'}
<a href="{$pic_dir}{$picture.value}" alvo="_blank">Abrir arquivo anexadoa>
{else}
<img src="{$pic_dir}{$picture.value}_small" alt="" />
{/se}
<a href="{$link->getProductDeletePictureLink($product, $field.id_customization_field)|escape:'html':'UTF-8'}" título="{l s='Excluir'}" >
<img src="{$img_dir}icon/delete.gif" alt="{l s='Excluir'}" class="customization_delete_icon" largura="11" altura="13" />
a>
{/foreach}
- Agora, último passo: abra "/ps-admin/themes/default/template/controllers/orders/_customized_data.tpl", pesquise por "Product::CUSTOMIZE_FILE", comente o primeiro foreach e cole este código acima:
{foreach de=$datas item=dados}
<div class="form-group">
<span class="rótulo-de-controle-col-lg-4"><forte>{se $dados['nome']}{$dados['nome']}{senão}{l s='Imagem #'}{$data@iteration}{/if}forte>span>
<div class="col-lg-8">
{se substr(nomebase($dados.valor), 0, 1) == 'P'}
<a href="{$pic_dir}{$data.value}" alvo="_blank">Abrir arquivo anexadoa>
{senão}
<a href="displayImage.php?img={$data['value']}&name={$order->id|intval}-file{$data@iteration}" class="_blank">
<img class="img-miniatura" src="{$smarty.const._THEME_PROD_PIC_DIR_}{$data['valor']}_pequeno" alt=""/>
a>
{/se}
div>
div>
{/foreach}
Pergunta nº 3: Criei 2 novos arquivos nas páginas de personalização de produtos, mas não fiquei satisfeito depois de criá-los. Como o usuário tem que ir até o final e clicar nas guias adicionais. Posso mover esses campos para o mesmo lugar onde existe o menu suspenso de combinação de produtos? Tentei fazer isso movendo o código do rodapé para outros lugares, como product.tpl, mas não ajudou.
Resposta: Você pode fazer isso pelo seguinte método.
Arquivo:
/themes/your-template/product.tpl
Encontre e exclua o seguinte código:
{if isset($product) && $product->customizable}
<divid="idTab10"class="bullet customization_block">
<formmethod="post"action="{$customizationFormTarget}"enctype="multipart/form-data"id="customizationForm"class="clearfix">
<pclass="infoCustomizable">
{l s='Depois de salvar seu produto personalizado, lembre-se de adicioná-lo ao seu carrinho.'}
{if $product->uploadable_files}
{l s='Os formatos de arquivo permitidos são: GIF, JPG, PNG'}{/if}
{if $product->uploadable_files|intval}
<divclass="customizableProductsFile">
{l s='Imagens'}
<ulid="uploadable_files"class="clearfix">
{counter start=0 assign='customizationField'}
{foreach from=$customizationFields item='field' name='customizationFields'}
{if $field.type == 0}
<liclass="customizationUploadLine{if $field.required} obrigatório{/if}">{assign var='key' valor='pictures_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field}
{if isset($pictures.$key)}
<divclass="customizationUploadBrowse">
<imgsrc="{$pic_dir}{$pictures.$key}_small"alt=""/>
<imgsrc="{$img_dir}icon/delete.gif"alt="{l s='Excluir'}"class="customization_delete_icon"width="11"height="13"/>
{/if}
<divclass="customizationUploadBrowse">
<labelclass="customizationUploadBrowseDescription">{if !empty($field.name)}{$field.name}{else}{l s='Selecione um arquivo de imagem do seu computador'}{/if}{if $field.required}*{/if}
<inputtype="file"name="file{$field.id_customization_field}"id="img{$customizationField}"class="customization_block_input {if isset($pictures.$key)}preenchido{/if}"/>
{contador}
{/if}
{/foreach}
{/if}
{if $product->text_fields|intval}
<divclass="customizableProductsText">
{l s='Texto'}
<ulid="text_fields">
{contador start=0 atribuir='customizationField'}
{foreach from=$customizationFields item='field' name='customizationFields'}
{if $field.type == 1}
<liclass="customizationUploadLine{if $field.required} obrigatório{/if}">
<labelfor="textField{$customizationField}">{atribuir var='key' value='textFields_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field} {if !empty($field.name)}{$field.name}{/if}{if $field.required}*{/if}
<textareatype="text"name="textField{$field.id_customization_field}"id="textField{$customizationField}"rows="1"cols="40"class="customization_block_input">{if isset($textFields.$key)}{$textFields.$key|stripslashes}{/if}
{counter}
{/if}
{/foreach}
{/if}
<pid="customizedDatas">
<inputtype="hidden"name="quantityBackup"id="quantityBackup"value=""/>
<inputtype="hidden"name="submitCustomizedDatas"value="1"/>
<inputtype="button"class="button"value="{l s='Salvar'}"onclick="javascript:saveCustomization()"/>
<spanid="ajax-loader"style="display:none"><imgsrc="{$img_ps_dir}loader.gif"alt="loader"/>
<pclass="clear required">* {l s='required fields'}
{/if}
-------
E antes desta linha:
{if (isset($product) && $product->description) || (isset($features) && $features) || (isset($acessórios) && $acessórios) || (isset($HOOK_PRODUCT_TAB) && $HOOK_PRODUCT_TAB) || (isset($anexos) && $anexos) || isset($product) && $product->customizable}
Cole este código:
{if isset($product) && $product->customizable}
<divclass="bullet customization_block">
<formmethod="post"action="{$customizationFormTarget}"enctype="multipart/form-data"id="customizationForm"class="clearfix">
<pclass="infoCustomizable">
{l s='After salvando seu produto personalizado, lembre-se de adicioná-lo ao seu carrinho.'}
{if $product->uploadable_files}
{l s='Os formatos de arquivo permitidos são: GIF, JPG, PNG'}{/if}
{if $product->uploadable_files|intval}
<divclass="customizableProductsFile">
{l s='Imagens'}
<ulid="uploadable_files"class="clearfix">
{counter start=0 assign='customizationField'}
{foreach from=$customizationFields item='field' name='customizationFields'}
{if $field.type == 0}
<liclass="customizationUploadLine{if $field.required} obrigatório{/if}">{assign var='key' valor='imagens_'|cat:$produto->id|cat:'_'|cat:$campo.id_campo_de_personalização}
<código> {if isset($imagens.$chave)}
<código> <divclass="personalizaçãoUploadBrowse">
<código>
<código>
<código> <imgsrc="{$img_dir}ícone/delete.gif"alt="{l s='Excluir'}"class="customization_delete_icon"width="11"height="13"/>
<código>
<código>
{/if}
<divclass="customizationUploadBrowse">
<labelclass="customizationUploadBrowseDescription">{if !empty($field.name)}{$field.name}{else}{l s='Selecione um arquivo de imagem do seu computador'}{/if}{if $field.required}*{/if}
<inputtype="file"name="file{$field.id_customization_field}"id="img{$customizationField}"class="customization_block_input {if isset($pictures.$key)}preenchido{/if}"/>
{contador}
<código> {/if}
<código> {/foreach}
<código>
<código>
<código> {/if}
<código> {se $produto->text_fields|intval}
<código> <divclass="texto_de_produtos_personalizáveis">
<código>
{l s='Texto'}
<ulid="text_fields">
{counter start=0 assign='customizationField'}
{foreach from=$customizationFields item='field' name='customizationFields'}
{if $field.type == 1}
<liclass="customizationUploadLine{if $field.required} required{/if}">
<labelfor="textField{$customizationField}">{assign var='key' value='textFields_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field} {if !empty($field.name)}{$field.name}{/if}{if $field.required}*{/if}
<textareatype="text"name="textField{$field.id_customization_field}"id="textField{$customizationField}"rows="1"cols="40"class="customization_block_input">{if isset($textFields.$key)}{$textFields.$key|stripslashes}{/if}
<código>
<código> {contador}
<código> {/if}
<código> {/foreach}
<código>
<código>
<código> {/if}
<código><pid="customizedDatas">
<inputtype="hidden"name="quantityBackup"id="quantityBackup"value=""/>
<inputtype="hidden"name="submitCustomizedDatas"value="1"/>
<inputtype="button"class="button"value="{l s='Salvar'}"onclick="javascript:saveCustomization()"/>
<spanid="ajax-loader"style="display:none"><imgsrc="{$img_ps_dir}loader.gif"alt="loader"/>
<pclass="limpar obrigatório">* {l s='campos obrigatórios'}
{/if}
----
Após a pesquisa:
{if isset($product)&& $product->customizable}
{l s='Customização do produto'}
{/if}
alterar por
{* {if isset($product)&& $product->customizable}
{l s='Customização do produto'}
{/if}
*}
Observação: para modificar product.tpl, você precisa fazer force compilação.
Pergunta nº 4: Quero mostrar a aba de personalização do produto ao lado da aba mais informações. No momento, ela está sendo exibida abaixo das abas padrão.
Resposta: Olá!
Editar product.tpl
Alterar
{if $product->description || $features || $accessories || $HOOK_PRODUCT_TAB || $attachments}
para
{if $product->description || $features || $accessories || $HOOK_PRODUCT_TAB || $attachments || $product->customizable}
Em
, acima de {$HOOK_PRODUCT_TAB} insira a linha:
{if $product->customizable}
{l s='Customização do produto'}
{/if}
Em
, acima de {$HOOK_PRODUCT_TAB_CONTENT} insira:
{if $product->customizable}
{l s='Após salvar seu produto personalizado, lembre-se de adicioná-lo ao seu carrinho.'}
{if $product->uploadable_files}
{l s='Os formatos de arquivo permitidos são: GIF, JPG, PNG'}{/if}
{if $product->uploadable_files|intval}
{l s='Imagens'}
{counter start=0 assign='customizationField'}
{foreachfrom=$customizationFields item='field' name='customizationFields'}
{if $field.type ==0}
{assign var='key' value='pictures_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field}
{if isset($pictures.$key)}
<código>
<código>
<código>
<código>{/if}
{counter}
{/if}
{/foreach}
<código>
<código> {/if}
<código>
<código> {if $product->text_fields|intval}
<código>
{l s='Textos'}
<código>
<código> {counter start=0 assign='customizationField'}
<código> {foreachfrom=$customizationFields item='campo' nome='customizationFields'}
<código> {if $field.type ==1}
<código>
{assign var='key' value='textFields_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field}
<código> {if!empty($field.name)}{$field.name}{/if}{if $field.required}*{/if}