Toutes les clefs pour réussir dans le e-commerce

Mes modules Prestashop

Produits dématérialisés qui disparaissent sur Prestashop 1.5

Vous avez peut-être, comme moi, rencontré ce bug. Sans raison les fichiers des produits dématérialisés disparaissent. Le produit reste commandable mais plus aucun fichier n’est lié et il est donc impossible de le télécharger (pas d’envoi d’email spécifique aux produits téléchargeables ni de lien dans la commande). Voici un fix pour régler ce problème.

Après avoir longuement cherché j’ai compris que le problème survenait lorsqu’on enregistrait trop vite sa fiche produit dans l’admin. Ceci est dû à l’onglet produit dématérialisé qui n’a pas fini de se charger.

Voici donc un override pour régler le problème en attendant qu’il soit corrigé dans une future version.

Ajoutez le fichier “virtualproduct.tpl” dans le dossier “override/controllers/admin/templates/products/” et collez le code suivant dedans.


{*
* 2007-2012 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
*  @author PrestaShop SA <contact@prestashop.com>
*  @copyright  2007-2012 PrestaShop SA
*  @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
*  International Registered Trademark &amp;amp; Property of PrestaShop SA
*}

<script type="text/javascript">
	var newLabel = '{l s='New label'}';
	var choose_language = '{l s='Choose language:'}';
	var required = '{l s='required'}';
	var customizationUploadableFileNumber = '{$product->uploadable_files}';
	var customizationTextFieldNumber = '{$product->text_fields}';
	var uploadableFileLabel = 0;
	var textFieldLabel = 0;

	function uploadFile()
	{
		$.ajaxFileUpload (
			{
				url:'./uploadProductFile.php',
				secureuri:false,
				fileElementId:'virtual_product_file',
				dataType: 'xml',
				success: function (data, status)
				{
					data = data.getElementsByTagName('return')[0];
					var result = data.getAttribute("result");
					var msg = data.getAttribute("msg");
					var fileName = data.getAttribute("filename");
					if (result == "error")
					{
						$("#upload-confirmation").hide();
						$("#upload-error td").html('<div class="error">{l s='Error:'} ' + msg + '</div>');
						$("#upload-error").show();
					}
					else
					{
						$('#upload-error').hide();
						$('#file_missing').hide();
						$('#virtual_product_name').attr('value', fileName);
						$("#upload-confirmation .error").remove();
						$('#upload-confirmation div').prepend('<span>{l s='The file'}&amp;amp;nbsp;"<a class="link" href="get-file-admin.php?file='+msg+'&amp;amp;filename='+fileName+'">'+fileName+'</a>"&amp;amp;nbsp;{l s='has successfully been uploaded'}' +
							'<input type="hidden" id="virtual_product_filename" name="virtual_product_filename" value="' + msg + '" /></span>');
						$("#upload-confirmation").show();
					}
				}
			}
		);
	}

	function uploadFile2()
	{
			var link = '';
			$.ajaxFileUpload (
			{
				url:'./uploadProductFileAttribute.php',
				secureuri:false,
				fileElementId:'virtual_product_file_attribute',
				dataType: 'xml',
				success: function (data, status)
				{
					data = data.getElementsByTagName('return')[0];
					var result = data.getAttribute("result");
					var msg = data.getAttribute("msg");
					var fileName = data.getAttribute("filename");
					if(result == "error")
						$("#upload-confirmation2").html('<p>error: ' + msg + '</p>');
					else
					{
						$('#virtual_product_file_attribute').remove();
						$('#virtual_product_file_label').hide();
						$('#file_missing').hide();
						$('#delete_downloadable_product_attribute').show();
						$('#upload-confirmation2').html(
							'<a class="link" href="get-file-admin.php?file='+msg+'&amp;amp;filename='+fileName+'">{l s='The file'}&amp;amp;nbsp;"' + fileName + '"&amp;amp;nbsp;{l s='has successfully been uploaded'}</a>' +
							'<input type="hidden" id="virtual_product_filename_attribute" name="virtual_product_filename_attribute" value="' + msg + '" />');
						$('#virtual_product_name_attribute').attr('value', fileName);

						link = $("#delete_downloadable_product_attribute").attr('href');
						$("#delete_downloadable_product_attribute").attr('href', link+"&amp;amp;file="+msg);
					}
				}
			}
		);
	}

</script>

<input type="hidden" name="submitted_tabs[]" value="VirtualProduct" />
<h4>{l s='Virtual Product (services, booking and downloadable products)'}</h4>
<div class="separation"></div>
<div>
	<div class="is_virtual_good">
		<input type="checkbox" id="virtual_tab_product_loaded" name="virtual_tab_product_loaded" value="true" checked="checked" />
		<input type="checkbox" id="is_virtual_good" name="is_virtual_good" value="true" {if $product->is_virtual &amp;amp;&amp;amp; $product->productDownload->active}checked="checked"{/if} />
			<label for="is_virtual_good" class="t bold">{l s='Is this a virtual product?'}</label>
	</div>
	{* [begin] virtual product *}
	<div id="virtual_good" {if !$product->productDownload->id || $product->productDownload->active}style="display:none"{/if} >
		<div>
			<label>{l s='Does this product have an associated file?'}</label>
			<label style="width:50px"><input type="radio" value="1"  name="is_virtual_file" {if $product_downloaded}checked="checked"{/if} />{l s='Yes'}</label>
			<label style="width:50px;"><input type="radio" value="0" name="is_virtual_file" {if !$product_downloaded}checked="checked"{/if} />{l s='No'}</label>
		</div><br />
		<div class="separation"></div>
		{if $download_product_file_missing}
			<p class="alert" id="file_missing">
				<b>{$download_product_file_missing} :<br/>
				{$smarty.const._PS_DOWNLOAD_DIR_}/{$product->productDownload->filename}</b>
			</p>
		{/if}

		<div id="is_virtual_file_product" style="display:none;">
			{if !$download_dir_writable}
				<p class="alert">
					{l s='Your download repository is not writable.'}<br/>
					{$smarty.const._PS_DOWNLOAD_DIR_}
				</p>
			{/if}
			{* Don't display file form if the product has combinations *}
			{if empty($product->cache_default_attribute)}
				{if $product->productDownload->id}
					<input type="hidden" id="virtual_product_id" name="virtual_product_id" value="{$product->productDownload->id}" />
				{/if}
				<table cellpadding="5" style="float: left; margin-left: 10px;">
					<tr id="upload_input" {if $is_file}style="display:none"{/if}>
						<td class="col-left">
							<label id="virtual_product_file_label" for="virtual_product_file" class="t">{l s='Upload a file'}</label>
						</td>
						<td class="col-right">
							<input type="file" id="virtual_product_file" name="virtual_product_file" onchange="uploadFile();" maxlength="{$upload_max_filesize}" />
							<p class="preference_description">{l s='Your server\'s maximum upload file size is'}:&amp;amp;nbsp;{$upload_max_filesize} {l s='MB'}</p>
						</td>
					</tr>
					<tr id="upload-error" style="display:none">
						<td colspan=2></td>
					</tr>
					<tr id="upload-confirmation" style="display:none">
						<td colspan=2>
							{if $up_filename}
								<input type="hidden" id="virtual_product_filename" name="virtual_product_filename" value="{$up_filename}" />
							{/if}
							<div class="conf">
								<a class="delete_virtual_product" id="delete_downloadable_product" onclick="return confirm('{l s='Delete this file'}')" href="{$currentIndex}&amp;amp;deleteVirtualProduct=true&amp;amp;token={$token}&amp;amp;id_product={$product->id}" class="red">
									<img src="../img/admin/delete.gif" alt="{l s='Delete this file'}"/>
								</a>
							</div>
						</td>
					</tr>
					{if $is_file}
						<tr>
							<td class="col-left">
								<input type="hidden" id="virtual_product_filename" name="virtual_product_filename" value="{$product->productDownload->filename}" />
								<label class="t">{l s='Link to the file:'}</label>
							</td>
							 <td class="col-right">
								{$product->productDownload->getHtmlLink(false, true)}
								<a onclick="return confirm('{l s='Delete this file'})')" href="{$currentIndex}&amp;amp;deleteVirtualProduct=true&amp;amp;token={$token}&amp;amp;id_product={$product->id}" class="red delete_virtual_product">
									<img src="../img/admin/delete.gif" alt="{l s='Delete this file'}"/>
								</a>
							</td>
						</tr>
					{/if}
					<tr>
						<td class="col-left">
							<label for="virtual_product_name" class="t">{l s='Filename'}</label>
						</td>
						<td class="col-right">
							<input type="text" id="virtual_product_name" name="virtual_product_name" style="width:200px" value="{$product->productDownload->display_filename|escape:'htmlall':'UTF-8'}" />
							<p class="preference_description" name="help_box">{l s='The full filename with its extension (e.g. Book.pdf)'}</p>
						</td>
					</tr>
					<tr>
						<td class="col-left">
							<label for="virtual_product_nb_downloable" class="t">{l s='Number of allowed downloads'}</label>
						</td>
						<td class="col-right">
							<input type="text" id="virtual_product_nb_downloable" name="virtual_product_nb_downloable" value="{$product->productDownload->nb_downloadable|htmlentities}" class="" size="6" />
							<p class="preference_description">{l s='Number of allowed downloads per customer - (Set to 0 for unlimited downloads)'}</p>
						</td>
					</tr>
					<tr>
						<td class="col-left">
							<label for="virtual_product_expiration_date" class="t">{l s='Expiration date'}</label>
						</td>
						<td class="col-right">
							<input class="datepicker" type="text" id="virtual_product_expiration_date" name="virtual_product_expiration_date" value="{$product->productDownload->date_expiration}" size="11" maxlength="10" autocomplete="off" /> {l s='Format: YYYY-MM-DD'}
							<p class="preference_description">{l s='If set, the file will not be downloadable anymore after this date. Leave this blank for no expiration date'}</p>
						</td>
					</tr>
						<td class="col-left">
							<label for="virtual_product_nb_days" class="t">{l s='Number of days'}</label>
						</td>
						<td class="col-right">
							<input type="text" id="virtual_product_nb_days" name="virtual_product_nb_days" value="{$product->productDownload->nb_days_accessible|htmlentities}" class="" size="4" /><sup> *</sup>
							<p class="preference_description">{l s='How many days this file can be accessed by customers'} - <em>({l s='Set to zero for unlimited access'})</em></p>
						</td>
					</tr>
					{* Feature not implemented *}
					{*<tr>*}
						{*<td class="col-left">*}
							{*<label for="virtual_product_is_shareable" class="t">{l s='is shareable'}</label>*}
						{*</td>*}
						{*<td class="col-right">*}
							{*<input type="checkbox" id="virtual_product_is_shareable" name="virtual_product_is_shareable" value="1" {if $product->productDownload->is_shareable}checked="checked"{/if} />*}
							{*<span class="hint" name="help_box" style="display:none">{l s='Specify if the file can be shared'}</span>*}
						{*</td>*}
					{*</tr>*}
				{else}
					<div class="hint clear" style="display: block;width: 70%;">{l s='You cannot edit your file here because you used combinations. Please edit it in the Combinations tab'}</div>
					<br />
					{$error_product_download}
				{/if}
			</table>
		</div>
	</div>
	<div style="clear:both"></div>
</div>

Pour ceux qui voudraient mieux comprendre j’ai simplement rajouté une checkbox en ligne 113:


<input type="checkbox" id="virtual_tab_product_loaded" name="virtual_tab_product_loaded" value="true" checked="checked" />

Il faut ensuite faire un override de la fonction “updateDownloadProduct” du controller “AdminProductsController”.
Ouvrez le fichier “override/controllers/admin/AdminProductsController.php” et collez-y le code suivant:


<?php

class AdminProductsController extends AdminProductsControllerCore
{
public function updateDownloadProduct($product, $edit = 0)
	{
		if(Tools::getValue('virtual_tab_product_loaded')!="true") 
			return false;
		
		$is_virtual_file = (int)Tools::getValue('is_virtual_file');
		$product->setDefaultAttribute(0);//reset cache_default_attribute
		// add or update a virtual product
		if (Tools::getValue('is_virtual_good') == 'true')
		{
			if (Tools::getValue('virtual_product_expiration_date') &amp;amp;&amp;amp; !Validate::isDate(Tools::getValue('virtual_product_expiration_date') &amp;amp;&amp;amp; !empty($is_virtual_file)))
			{
				if (!Tools::getValue('virtual_product_expiration_date'))
				{
					$this->errors[] = Tools::displayError('This field expiration date attribute is required.');
					return false;
				}
			}

			// Trick's
			if ($edit == 1)
			{
				$id_product_download = (int)ProductDownload::getIdFromIdProduct((int)$product->id);
				if (!$id_product_download)
					$id_product_download = (int)Tools::getValue('virtual_product_id');
			}
			else
				$id_product_download = Tools::getValue('virtual_product_id');

			$is_shareable = Tools::getValue('virtual_product_is_shareable');
			$virtual_product_name = Tools::getValue('virtual_product_name');
			$virtual_product_filename = Tools::getValue('virtual_product_filename');
			$virtual_product_nb_days = Tools::getValue('virtual_product_nb_days');
			$virtual_product_nb_downloable = Tools::getValue('virtual_product_nb_downloable');
			$virtual_product_expiration_date = Tools::getValue('virtual_product_expiration_date');

			if ($virtual_product_filename)
				$filename = $virtual_product_filename;
			else
				$filename = ProductDownload::getNewFilename();

			$download = new ProductDownload((int)$id_product_download);
			$download->id_product = (int)$product->id;
			$download->display_filename = $virtual_product_name;
			$download->filename = $filename;
			$download->date_add = date('Y-m-d H:i:s');
			$download->date_expiration = $virtual_product_expiration_date ? $virtual_product_expiration_date.' 23:59:59' : '';
			$download->nb_days_accessible = (int)$virtual_product_nb_days;
			$download->nb_downloadable = (int)$virtual_product_nb_downloable;
			$download->active = 1;
			$download->is_shareable = (int)$is_shareable;

			if ($download->save())
				return true;
		}
		else
		{
			// unactive download product if checkbox not checked 
			if ($edit == 1)
			{
				$id_product_download = (int)ProductDownload::getIdFromIdProduct((int)$product->id);
				if (!$id_product_download)
					$id_product_download = (int)Tools::getValue('virtual_product_id');
			}
			else
				$id_product_download = ProductDownload::getIdFromIdProduct($product->id);

			if (!empty($id_product_download))
			{
				$product_download = new ProductDownload((int)$id_product_download);
				$product_download->date_expiration = date('Y-m-d H:i:s', time() - 1);
				$product_download->active = 0;
				return $product_download->save();
			}
		}
		return false;
	}
}


Poster un Commentaire

27 Commentaires sur "Produits dématérialisés qui disparaissent sur Prestashop 1.5"

Recevoir un email pour
avatar
Trier par:   plus récent | plus vieux | Plus de vote
Arnaud
Invité
Arnaud

Bonjour,

Mon fichier “override/controllers/admin/AdminProductsController.php” contient que une ligne c’est normal ?

Si je le modifie, impossible d’acceder aux produits : ” Le site Web a rencontré une erreur lors de l’extraction de http://www.*****.fr/admin*****/index.php?controller=AdminProducts&token=6137b6adb6ea5d5dc7edfef8c5bf09c7. Cela peut être dû à une opération de maintenance ou à une configuration incorrecte. ”

Et je n’ai pas de dossier “products” dans “override/controllers/admin/templates/” c’est normal ? Il faut l’ajouter ?

Je suis en 1.5.2.0

Merci

Arnaud
Invité
Arnaud

Merci !

Alors j’ai trouvé mon problème ! Je suis bête :)

Attention, il ne suffit pas de faire un copié/collé…

Il faut remplacer dans le code, les caractères spéciaux HTML => ” & ” en ” & ” et les ”   ” en ” “.

Et forcément après ça marche mieux :)

Merci

Arnaud
Invité
Arnaud

Aïe c’est pas passé :
Il faut remplacer dans le code, les caractères spéciaux HTML
=> » & a m p ; » en » & » et les » & n b s p ; » en » « .

Tortuga
Invité
Tortuga

bonjour a tous
je suis en versions 1.5.3.1
mon probleme est que le detail produit n’apparait pas dans l’admin de commande et dans la facture pdf mais j’ai le bon montant sans la le detail produit et cela uniquement pour les produit dematerialisé
est ce la meme procedure a suivre

merci d’avance

Tortuga
Invité
Tortuga

vous savez ou est ce que je peux chercher
car quand j’ajoute en manuel dans l’admin les produit apparaise

PrestaEdit
Invité

Bonjour,

Je n’ai pas encore testé la modification mais, pour mon info: est-ce que celle-ci a été proposée via GitHub ? ;-)

Cordialement,
J. Danse.

xavdpub
Invité

bonjour
je suis concerné par le pb mais contrairement à Arnaud , je n arrive pas à le faire tourner sur 1.5.2
j ai remplacé les &nbsp mais je ne trouve pas les &a m p
Serait il possible de recevoir le fichiers “clean” “ready to use” ?
D’avance un grand merci
Xavier

xavdpub
Invité

Re bonjour
J arrive à ne plus avoir l’erreur , en revanche l upload de fichier se lance et semble ne jamais s arreter (message chargement et roue qui tourne sans fin alors que le fichier ne pese que 918Ko) Pourriez vous m’aider ?
PEut etre que les fichiers clean aideraient car j ai vu que certaines instruction avec un pb de typo (eg : secureuri au lieu de secureurl mais je ne suis pas un expert pour les checker toutes
D’avance merci.
Xavier

xavdpub
Invité

Merci pour la réponse rapide.
Les droits d access sont bons car j arrive à uploader le même fichier avec les modules natifs mais ils disparaissent par la suite …
dans le fichier ci-dessus, je vois encore des “&nbsp” dont parle Arnaud, j ai aussi quelques doutes sur des “-” au lieu de “_” ainsi que “secureuri” vs “secureurl”
je n ai aucun doute sur le fichier mais il semble que son integration dans la page ci-dessus joue des tours à la typo donc à la programmation. N’étant pas programmeur, je n arrive pas à le checker
Arnaud mentionne qu il arrive à le faire tourner sur 1.5.2
cdt

xavdpub
Invité

Bonsoir
Ca marche sous 1.5..2 ! mais pour info dans le fichier ci-dessus il m a fallu remplacer des &nsbp par des blancs et remplacer secureuri par secureurl
Juste une question :
Faut il que je re uploade tous mes fichiers avec ce module ou permet il de stabiliser aussi ceux déjà téléchargés avec le module natif
Un grand merci en tout cas !!

xavdpub
Invité

Bon beh…en fait ça uploade mais ensuite quand je reviens sur la fiche produit dans le BO le fichier a disparu. C’est pire qu avant.
J ai peut etre un pb de syntaxe que je n ai pas vu.
S il y a un moyen de recuperer les fichiers ci dessus autrement que par ce site, je t en serais très reconnaissant. Je garde espoir car Arnaud le fait tourner sur 1.5.2
D’avance merci

Arnaud
Invité
Arnaud

Bonjour,

J’ai fait le ménage dans la base de données !
Car mes fichiers étaient en double voir en triple dans la table ‘ps_product_download’.

J’ai donc supprimé en brut certaines lignes de la table, et j’ai pris soin de garder le ‘filename’ pour supprimer le fichier du ftp (dossier download).

( Pour le moment tout est OK pour moi sur la 1.5.2 )

Arnaud
Invité
Arnaud

Pas de souci !

Sinon je vous invite à créer la requête suivante dans Paramètres avancés > SQL Manager :

SELECT p.id_product, p.reference,p.uploadable_files,pd.id_product,pd.id_product_download, pd.filename, pd.display_filename,pd.date_add,pd.nb_downloadable, pd.active,p.is_virtual,pl.name FROM ps_product p LEFT JOIN ps_product_lang pl ON (p.id_product = pl.id_product) LEFT JOIN ps_product_download pd ON (p.id_product = pd.id_product) WHERE pl.id_lang = 4

Elle vous permettra de visualiser d’un coup d’oeil les problèmes sur les fichiers dématérialisés, très pratique (Attention à la langue ici > pl.id_lang = 4, c’est pour le français )
;)

xavdpub
Invité

Pour les lecteurs de l article. Ca marche ! (version 1.5.2)
En fait les codes ci dessus sont à utiliser tel quels (déjà corrigés)
Le cas échéant attendre un peu que le serveur active bien les fichiers avant de telecharger.
Vider le cache du navigateur avant de commencer le téléchargement.
Un grand merci pour votre aide !!

xavdpub
Invité

@ Arnaud
En ce qui concerne la requete , y a t il un paramétrage particulier ?
J’ai un message d erreur disant : l attribut filename n existe pas dans la base ps_products_download, idem pour date_add etc…
D’avance merci

julie
Invité
julie

bonjour,
je rencontre le même soucis sous 1.5.4.1
je n’ai pas le fichier « AdminProductsController » dans
override/controllers/admin/AdminProductsController.php il se trouve dans controllers/admin.
dois je modifier le fichier ou faire une copie que je place dans override ? si je fais une copie je garde tout le code du fichier et je rajoute ton code ou je mets juste ton code??
merci pour ton aide
Julie

julie
Invité
julie

super merci pour ta réponse rapide :)

wpDiscuz