Cómo duplicar y modificar un formulario de contacto en Prestashop

kary83 Seguir

Curioso
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Desde
14 Abr 2014
Mensajes
7
Buenos días,

Estoy intentando duplicar el formulario de contacto porque tengo que tener dos diferentes y no puedo comprar un módulo para ello.

Hasta ahora lo que he hecho es lo que he encontrado en diferentes mensajes del foro oficial de prestashop (en español e inglés) en el que también he consultado pero aún no me han podido dar solución:

He duplicado y renombrado tres archivos:
/contact-form.php -> distribuidor-form.php
/controles/front/ContactControler.php -> /controllers/front/DistribuidorController.php
/themes/mitema/contact-form.tpl -> /themes/mitema/distribuidor-form.php

Después he entrado eh distribuidor-form.php y he modificado la línea de la ruta poniendo contorller=ditribuidor

En el DitribuidorController.php he cambiado tres líneas:
El nombre de la clase: class DistribuidorControllerCore extends FrontController
La variable pública: public $php_self = 'distribuidor';
La dirección del tpl: $this->setTemplate(_PS_THEME_DIR_.'distribuidor-form.tpl');

Por último añado un enlace en la página que me lleve a index.php?controller=distribuidor. También he probado a poner en el enlace {$link->getPageLink('distribuidor.php', true)} con igual resultado

Más adelante haré los cambios en la base de datos y mail para que se registre y envíe correos, pero antes pruebo que funcione... No funciona....elimino el class_index.php de la caché y el formulario de contacto sigue funcionando bien pero cuando le doy al enlace para abrir el formulario de distribuidor me sale "404 página no encontrada"

La verdad es que por más vueltas que doy no encuentro donde está el error, he comprobado que esté bien escrito distribuidor en todas partes (pues a veces parece que tengo un poco de dislexia e intercambio letras) y está bien, no se si es que me falta algo por cambiar...

Muchas gracias de antemano!
 

Emanuel Andrei

Dseda
Programador
Verificación en dos pasos activada
Verificado por Whatsapp
Desde
1 Nov 2013
Mensajes
1.219
Te has asegurado que dentro de cada archivo el codigo esta bien, redireccionando donde debe?
 

kary83

Curioso
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Desde
14 Abr 2014
Mensajes
7
Hola EmiLL,

Gracias por responder y tan rápido! Pues en principio he seguido los pasos de los "tutoriales" del foro de prestashop, pero no se si es que falte algún paso o es que hay que hacer algo más y se de por supuesto. Yo he buscado en todo el código de los tres archivos y la verdad es que no he encontrado nada, lo único hace dos referencias a un js y un css del contacto pero entiendo por lo que he mirado que es sólo para el estilo y funcionalidad, lo que no tiene sentido que si fuera eso ni siquiera entre, pero el js no le veo ninguna cosa a modificar, además que en los "tutoriales" sólo habla de duplicar esos tres archivos y cambiar esas líneas, de ahí mi duda.

Si es preciso pego el código de los tres archivos o si se puede los subo.

Muchas gracias!
 

Emanuel Andrei

Dseda
Programador
Verificación en dos pasos activada
Verificado por Whatsapp
Desde
1 Nov 2013
Mensajes
1.219
Hola kary83.

Pega aqui el formulario de contacto de la pagina de donde te ha dado el error 404 si es posible.

Gracias.
 

kary83

Curioso
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Desde
14 Abr 2014
Mensajes
7
Faltaría más!

Pongo el código de los tres archivos implicados:

distribuidor.php
PHP:
require(dirname(__FILE__).'/config/config.inc.php');
Tools::displayFileAsDeprecated();

Tools::redirect('index.php?controller=distribuidor'.((count($_GET) || count($_POST)) ? '&'.http_build_query(array_merge($_GET, $_POST), '', '&') : ''), __PS_BASE_URI__, null, 'HTTP/1.1 301 Moved Permanently');

DistribuidorController.php
PHP:
class DistribuidorControllerCore extends FrontController
{
	public $php_self = 'distribuidor';
	public $ssl = true;

	/**
	 * Start forms process
	 * @see FrontController::postProcess()
	 */
	public function postProcess()
	{
		if (Tools::isSubmit('submitMessage'))
		{
			$extension = array('.txt', '.rtf', '.doc', '.docx', '.pdf', '.zip', '.png', '.jpeg', '.gif', '.jpg');
			$fileAttachment = Tools::fileAttachment('fileUpload');
			$message = Tools::getValue('message'); // Html entities is not usefull, iscleanHtml check there is no bad html tags.
			if (!($from = trim(Tools::getValue('from'))) || !Validate::isEmail($from))
				$this->errors[] = Tools::displayError('Invalid email address.');
			else if (!$message)
				$this->errors[] = Tools::displayError('The message cannot be blank.');
			else if (!Validate::isCleanHtml($message))
				$this->errors[] = Tools::displayError('Invalid message');
			else if (!($id_contact = (int)(Tools::getValue('id_contact'))) || !(Validate::isLoadedObject($contact = new Contact($id_contact, $this->context->language->id))))
				$this->errors[] = Tools::displayError('Please select a subject from the list provided. ');
			else if (!empty($fileAttachment['name']) && $fileAttachment['error'] != 0)
				$this->errors[] = Tools::displayError('An error occurred during the file-upload process.');
			else if (!empty($fileAttachment['name']) && !in_array( Tools::strtolower(substr($fileAttachment['name'], -4)), $extension) && !in_array( Tools::strtolower(substr($fileAttachment['name'], -5)), $extension))
				$this->errors[] = Tools::displayError('Bad file extension');
			else
			{
				$customer = $this->context->customer;
				if (!$customer->id)
					$customer->getByEmail($from);

				$contact = new Contact($id_contact, $this->context->language->id);

				if (!((
						($id_customer_thread = (int)Tools::getValue('id_customer_thread'))
						&& (int)Db::getInstance()->getValue('
						SELECT cm.id_customer_thread FROM '._DB_PREFIX_.'customer_thread cm
						WHERE cm.id_customer_thread = '.(int)$id_customer_thread.' AND cm.id_shop = '.(int)$this->context->shop->id.' AND token = \''.pSQL(Tools::getValue('token')).'\'')
					) || (
						$id_customer_thread = CustomerThread::getIdCustomerThreadByEmailAndIdOrder($from, (int)Tools::getValue('id_order'))
					)))
				{
					$fields = Db::getInstance()->executeS('
					SELECT cm.id_customer_thread, cm.id_contact, cm.id_customer, cm.id_order, cm.id_product, cm.email
					FROM '._DB_PREFIX_.'customer_thread cm
					WHERE email = \''.pSQL($from).'\' AND cm.id_shop = '.(int)$this->context->shop->id.' AND ('.
						($customer->id ? 'id_customer = '.(int)($customer->id).' OR ' : '').'
						id_order = '.(int)(Tools::getValue('id_order')).')');
					$score = 0;
					foreach ($fields as $key => $row)
					{
						$tmp = 0;
						if ((int)$row['id_customer'] && $row['id_customer'] != $customer->id && $row['email'] != $from)
							continue;
						if ($row['id_order'] != 0 && Tools::getValue('id_order') != $row['id_order'])
							continue;
						if ($row['email'] == $from)
							$tmp += 4;
						if ($row['id_contact'] == $id_contact)
							$tmp++;
						if (Tools::getValue('id_product') != 0 && $row['id_product'] == Tools::getValue('id_product'))
							$tmp += 2;
						if ($tmp >= 5 && $tmp >= $score)
						{
							$score = $tmp;
							$id_customer_thread = $row['id_customer_thread'];
						}
					}
				}
				$old_message = Db::getInstance()->getValue('
					SELECT cm.message FROM '._DB_PREFIX_.'customer_message cm
					LEFT JOIN '._DB_PREFIX_.'customer_thread cc on (cm.id_customer_thread = cc.id_customer_thread)
					WHERE cc.id_customer_thread = '.(int)($id_customer_thread).' AND cc.id_shop = '.(int)$this->context->shop->id.'
					ORDER BY cm.date_add DESC');
				if ($old_message == $message)
				{
					$this->context->smarty->assign('alreadySent', 1);
					$contact->email = '';
					$contact->customer_service = 0;
				}

				if ($contact->customer_service)
				{
					if ((int)$id_customer_thread)
					{
						$ct = new CustomerThread($id_customer_thread);
						$ct->status = 'open';
						$ct->id_lang = (int)$this->context->language->id;
						$ct->id_contact = (int)($id_contact);
						if ($id_order = (int)Tools::getValue('id_order'))
							$ct->id_order = $id_order;
						if ($id_product = (int)Tools::getValue('id_product'))
							$ct->id_product = $id_product;
						$ct->update();
					}
					else
					{
						$ct = new CustomerThread();
						if (isset($customer->id))
							$ct->id_customer = (int)($customer->id);
						$ct->id_shop = (int)$this->context->shop->id;
						if ($id_order = (int)Tools::getValue('id_order'))
							$ct->id_order = $id_order;
						if ($id_product = (int)Tools::getValue('id_product'))
							$ct->id_product = $id_product;
						$ct->id_contact = (int)($id_contact);
						$ct->id_lang = (int)$this->context->language->id;
						$ct->email = $from;
						$ct->status = 'open';
						$ct->token = Tools::passwdGen(12);
						$ct->add();
					}

					if ($ct->id)
					{
						$cm = new CustomerMessage();
						$cm->id_customer_thread = $ct->id;
						$cm->message = $message;
						if (isset($fileAttachment['rename']) && !empty($fileAttachment['rename']) && rename($fileAttachment['tmp_name'], _PS_MODULE_DIR_.'../upload/'.basename($fileAttachment['rename'])))
							$cm->file_name = $fileAttachment['rename'];
						$cm->ip_address = ip2long(Tools::getRemoteAddr());
						$cm->user_agent = $_SERVER['HTTP_USER_AGENT'];
						if (!$cm->add())
							$this->errors[] = Tools::displayError('An error occurred while sending the message.');
					}
					else
						$this->errors[] = Tools::displayError('An error occurred while sending the message.');
				}

				if (!count($this->errors))
				{
					$var_list = array(
									'{order_name}' => '-',
									'{attached_file}' => '-',
									'{message}' => Tools::nl2br(stripslashes($message)),
									'{email}' =>  $from,
									'{product_name}' => '',
								);

					if (isset($fileAttachment['name']))
						$var_list['{attached_file}'] = $fileAttachment['name'];

					$id_order = (int)Tools::getValue('id_order');
					
					$id_product = (int)Tools::getValue('id_product');
					
					if (isset($ct) && Validate::isLoadedObject($ct) && $ct->id_order)
						$id_order = $ct->id_order;

					if ($id_order)
					{
						$order = new Order((int)$id_order);
						$var_list['{order_name}'] = $order->getUniqReference();
						$var_list['{id_order}'] = $id_order;
					}
					
					if ($id_product)
					{
						$product = new Product((int)$id_product);
						if (Validate::isLoadedObject($product) && isset($product->name[Context::getContext()->language->id]))
							$var_list['{product_name}'] = $product->name[Context::getContext()->language->id];
					}

					if (empty($contact->email))
						Mail::Send($this->context->language->id, 'contact_form', ((isset($ct) && Validate::isLoadedObject($ct)) ? sprintf(Mail::l('Your message has been correctly sent #ct%1$s #tc%2$s'), $ct->id, $ct->token) : Mail::l('Your message has been correctly sent')), $var_list, $from, null, null, null, $fileAttachment);
					else
					{					
						if (!Mail::Send($this->context->language->id, 'contact', Mail::l('Message from contact form').' [no_sync]',
							$var_list, $contact->email, $contact->name, $from, ($customer->id ? $customer->firstname.' '.$customer->lastname : ''),
									$fileAttachment) ||
								!Mail::Send($this->context->language->id, 'contact_form', ((isset($ct) && Validate::isLoadedObject($ct)) ? sprintf(Mail::l('Your message has been correctly sent #ct%1$s #tc%2$s'), $ct->id, $ct->token) : Mail::l('Your message has been correctly sent')), $var_list, $from, null, $contact->email, $contact->name, $fileAttachment))
									$this->errors[] = Tools::displayError('An error occurred while sending the message.');
					}
				}
				
				if (count($this->errors) > 1)
					array_unique($this->errors);
				else
					$this->context->smarty->assign('confirmation', 1);
			}
		}
	}

	public function setMedia()
	{
		parent::setMedia();
		$this->addCSS(_THEME_CSS_DIR_.'contact-form.css');
		$this->addJS(_THEME_JS_DIR_.'contact-form.js');
	}

	/**
	 * Assign template vars related to page content
	 * @see FrontController::initContent()
	 */
	public function initContent()
	{
		parent::initContent();

		$this->assignOrderList();

		$email = Tools::safeOutput(Tools::getValue('from',
		((isset($this->context->cookie) && isset($this->context->cookie->email) && Validate::isEmail($this->context->cookie->email)) ? $this->context->cookie->email : '')));
		$this->context->smarty->assign(array(
			'errors' => $this->errors,
			'email' => $email,
			'fileupload' => Configuration::get('PS_CUSTOMER_SERVICE_FILE_UPLOAD')
		));


		if (($id_customer_thread = (int)Tools::getValue('id_customer_thread')) && $token = Tools::getValue('token'))
		{
			$customerThread = Db::getInstance()->getRow('
				SELECT cm.* 
				FROM '._DB_PREFIX_.'customer_thread cm
				WHERE cm.id_customer_thread = '.(int)$id_customer_thread.' 
				AND cm.id_shop = '.(int)$this->context->shop->id.' 
				AND token = \''.pSQL($token).'\'
			');
			$this->context->smarty->assign('customerThread', $customerThread);
		}
		
		$this->context->smarty->assign(array(
			'contacts' => Contact::getContacts($this->context->language->id),
			'message' => html_entity_decode(Tools::getValue('message'))
		));

		$this->setTemplate(_PS_THEME_DIR_.'distribuidor-form.tpl');
	}

	/**
	 * Assign template vars related to order list and product list ordered by the customer
	 */
	protected function assignOrderList()
	{
		if ($this->context->customer->isLogged())
		{
			$this->context->smarty->assign('isLogged', 1);

			$products = array();
			$result = Db::getInstance()->executeS('
			SELECT id_order
			FROM '._DB_PREFIX_.'orders
			WHERE id_customer = '.(int)$this->context->customer->id.' ORDER BY date_add');
			$orders = array();
			foreach ($result as $row)
			{
				$order = new Order($row['id_order']);
				$date = explode(' ', $order->date_add);				
				$tmp = $order->getProducts();
				foreach ($tmp as $key => $val)
					$products[$row['id_order']][$val['product_id']] = array('value' => $val['product_id'], 'label' => $val['product_name']);
				$orders[] = array('value' => $order->id, 'label' => $order->getUniqReference().' - '.Tools::displayDate($date[0],null) , 'selected' => (int)Tools::getValue('id_order') == $order->id);
			}

			$this->context->smarty->assign('orderList', $orders);
			$this->context->smarty->assign('orderedProductList', $products);
		}
	}
}

distribuidor-form.tpl

Insertar CODE, HTML o PHP:
{capture name=path}{l s='Distribuidor'}{/capture}

 
<h1>{if isset($customerThread) && $customerThread}{l s='Your reply'}{else}{l s='Distribuidors'}{/if}</h1>

{if isset($confirmation)}
	<p>{l s='Your message has been successfully sent to our team.'}</p>
	<ul class="footer_links">
		<li><a href="{$base_dir}"><img class="icon" alt="" src="{$img_dir}icon/home.gif"/></a><a href="{$base_dir}">{l s='Home'}</a></li>
	</ul>
{elseif isset($alreadySent)}
	<p>{l s='Your message has already been sent.'}</p>
	<ul class="footer_links">
		<li><a href="{$base_dir}"><img class="icon" alt="" src="{$img_dir}icon/home.gif"/></a><a href="{$base_dir}">{l s='Home'}</a></li>
	</ul>
{else}
	<p class="bold">{l s='Si quieres ser distribuidor de Norman ponte en contacto con nosotros'}</p>
	{include file="$tpl_dir./errors.tpl"}
	<form action="{$request_uri|escape:'htmlall':'UTF-8'}" method="post" class="std form-horizontal" enctype="multipart/form-data">
		<fieldset>
			<!--<h3>{l s='send a message'}</h3>-->
			<div class="select control-group">
				<label for="id_contact" class="control-label">{l s='Subject Heading'}</label>
			{if isset($customerThread.id_contact)}
				{foreach from=$contacts item=contact}
					{if $contact.id_contact == $customerThread.id_contact}
					<div class="controls">
						<input type="text" id="contact_name" name="contact_name" value="{$contact.name|escape:'htmlall':'UTF-8'}" readonly="readonly" />
						<input type="hidden" name="id_contact" value="{$contact.id_contact}" />
					</div>
					{/if}
				{/foreach}
			</div>
			{else}
			<div class="controls">
				<select id="id_contact" name="id_contact" onchange="showElemFromSelect('id_contact', 'desc_contact')">
					<option value="0">info@mail.com</option>
				</select>
			</div>
			{/if}
			<div class="text control-group">
				<label for="empresa" class="control-label">{l s='Empresa'}</label>
				<div class="controls">
					{if isset($customerThread.email)}
						<input type="text" id="empresa" name="empresa" value="{$customerThread.empresa|escape:'htmlall':'UTF-8'}" readonly="readonly" />
					{else}
						<input type="text" id="empresa" name="empresa" value="{$empresa|escape:'htmlall':'UTF-8'}" />
					{/if}
				</div>
			</div>
			<div class="text control-group">
				<label for="email" class="control-label">{l s='Email address'}</label>
				<div class="controls">
					{if isset($customerThread.email)}
						<input type="text" id="email" name="from" value="{$customerThread.email|escape:'htmlall':'UTF-8'}" readonly="readonly" />
					{else}
						<input type="text" id="email" name="from" value="{$email|escape:'htmlall':'UTF-8'}" />
					{/if}
				</div>
			</div>

			
		<div class="textarea control-group">
			<label class="control-label" for="message">{l s='Message'}</label>
			<div class="controls">
				 <textarea id="message" name="message" rows="15" cols="10">{if isset($message)}{$message|escape:'htmlall':'UTF-8'|stripslashes}{/if}</textarea>
			</div>
		</div>
		<div class="submit control-group">
			<div class="controls">
				<input type="submit" name="submitMessage" id="submitMessage" value="{l s='Send'}" class="button_large btn" onclick="$(this).hide();" />

			</div>
		</div>
	</fieldset>
</form>
{/if}

Los tres son duplicados del formulario de contacto, que funciona bien, lo único los cambios indicados antes y en el tpl los campos que son diferentes y que luego debo modificar en el controller y en la bd así como en los mails para que se registren y se envíen pero eso es otra historia que ya conozco de las modificaciones del contact-form y funciona bien.

Muchas gracias!!!
 

zenok

Gamma
Programador
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Desde
6 May 2009
Mensajes
193
Hola, he trabajado muy poco en prestashop, pero creo que si estás tratando de acceder a la página index.php?controller=distribuidor, deberías revisar si en el fichero index.php existe alguna función que permite acceder a esas páginas. Sería lógico.
 

kary83

Curioso
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Desde
14 Abr 2014
Mensajes
7
Hola Znok, gracias por responder.

En el index.php así como el index.tpl no hay funciones para acceder a ninguna página, en tal caso redirige a config.inc.php pero ya he estado mirando ahí por si tenía que añadir el controller y tampoco he encontrado nada.

Prestashop es un poco particular y muy puñetero para cualquier cambio, la verdad es que cada vez que tengo que hacer algo me vuelvo loca, donde esté Joomla.... jejejeje en fin supongo cuestión de gustos (para que nadie se sienta ofendido jejeje sobre todo los proWordPress) uso prestashop cuando no tengo más remedio por estas cosas, pero en fin, ahora a tocado y no se como hacer para solucionar este problema :(

Gracias!!!
 

Emanuel Andrei

Dseda
Programador
Verificación en dos pasos activada
Verificado por Whatsapp
Desde
1 Nov 2013
Mensajes
1.219
Hola kary83.

Que regla tienes en el index para que te lleve al formulario de contacto ? Al hacer estas modificaciones, modificaste alli tambien?
 

kary83

Curioso
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Desde
14 Abr 2014
Mensajes
7
Hola EmiLL,

Como le comentaba al compañero anterior, en los index.php o index.tpl no hay ninguna regla que lleve a ningún sitio, en prestashop todo está dividido y se usan los controllers para una acción u otra, en el index.php lo unico que se referencia es el config.ini.php donde están todos los controles del sitio, en el index.tpl lo unico que se referencia es el hook home a partir de entonces todos los tpl van conformando la maqueta de la página y el cambio entre una u otra página se hace desde los controllers, los php de esa página o módulo que hacen la funcionalidad y los tpl que muestran el contenido de la misma

Vamos un jaleo macabeo u.u

---------- Post agregado el 16-abr-2014 hora: 15:34 ----------

Buenas tardes,

A nadie se le ocurre que puede ser? es lo único que me falta para terminar la web :(
 
J

jlafu

Hola kary83,

Yo me he encontrado con el mismo problema que tú, y al final lo he resuelto según proponen en el último comentario de este hilo: Create Custom Contact Form on CMS page - Theme development / Integration - PrestaShop Forums

La única pega que tiene es que prestashop no almacena el formulario enviado para poder consultarlo u obtener estadísticas desde el backend, pero los formularios se envían correctamente.

Ya dirás si esta solución te sirve!

PS: Aquí implementan lo mismo, pero en plan mucho más "fashion" (a mí me ha servido con el anteior): How to add a contact form to a CMS page? - Configuring & using PrestaShop - PrestaShop Forums
 
Arriba