1<?php
2/**
3 * @package     Joomla.Site
4 * @subpackage  com_contact
5 *
6 * @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved.
7 * @license     GNU General Public License version 2 or later; see LICENSE.txt
8 */
9
10defined('_JEXEC') or die;
11
12/**
13 * Controller for single contact view
14 *
15 * @since  1.5.19
16 */
17class ContactControllerContact extends JControllerForm
18{
19	/**
20	 * Method to get a model object, loading it if required.
21	 *
22	 * @param   string  $name    The model name. Optional.
23	 * @param   string  $prefix  The class prefix. Optional.
24	 * @param   array   $config  Configuration array for model. Optional.
25	 *
26	 * @return  JModelLegacy  The model.
27	 *
28	 * @since   1.6.4
29	 */
30	public function getModel($name = '', $prefix = '', $config = array('ignore_request' => true))
31	{
32		return parent::getModel($name, $prefix, array('ignore_request' => false));
33	}
34
35	/**
36	 * Method to submit the contact form and send an email.
37	 *
38	 * @return  boolean  True on success sending the email. False on failure.
39	 *
40	 * @since   1.5.19
41	 */
42	public function submit()
43	{
44		// Check for request forgeries.
45		$this->checkToken();
46
47		$app    = JFactory::getApplication();
48		$model  = $this->getModel('contact');
49		$stub   = $this->input->getString('id');
50		$id     = (int) $stub;
51
52		// Get the data from POST
53		$data = $this->input->post->get('jform', array(), 'array');
54
55		// Get item
56		$model->setState('filter.published', 1);
57		$contact = $model->getItem($id);
58
59		// Get item params, take menu parameters into account if necessary
60		$active = $app->getMenu()->getActive();
61		$stateParams = clone $model->getState()->get('params');
62
63		// If the current view is the active item and a contact view for this contact, then the menu item params take priority
64		if ($active && strpos($active->link, 'view=contact') && strpos($active->link, '&id=' . (int) $contact->id))
65		{
66			// $item->params are the contact params, $temp are the menu item params
67			// Merge so that the menu item params take priority
68			$contact->params->merge($stateParams);
69		}
70		else
71		{
72			// Current view is not a single contact, so the contact params take priority here
73			$stateParams->merge($contact->params);
74			$contact->params = $stateParams;
75		}
76
77		// Check if the contact form is enabled
78		if (!$contact->params->get('show_email_form'))
79		{
80			$this->setRedirect(JRoute::_('index.php?option=com_contact&view=contact&id=' . $stub . '&catid=' . $contact->catid, false));
81
82			return false;
83		}
84
85		// Check for a valid session cookie
86		if ($contact->params->get('validate_session', 0))
87		{
88			if (JFactory::getSession()->getState() !== 'active')
89			{
90				JError::raiseWarning(403, JText::_('JLIB_ENVIRONMENT_SESSION_INVALID'));
91
92				// Save the data in the session.
93				$app->setUserState('com_contact.contact.data', $data);
94
95				// Redirect back to the contact form.
96				$this->setRedirect(JRoute::_('index.php?option=com_contact&view=contact&id=' . $stub . '&catid=' . $contact->catid, false));
97
98				return false;
99			}
100		}
101
102		// Contact plugins
103		JPluginHelper::importPlugin('contact');
104		$dispatcher = JEventDispatcher::getInstance();
105
106		// Validate the posted data.
107		$form = $model->getForm();
108
109		if (!$form)
110		{
111			JError::raiseError(500, $model->getError());
112
113			return false;
114		}
115
116		if (!$model->validate($form, $data))
117		{
118			$errors = $model->getErrors();
119
120			foreach ($errors as $error)
121			{
122				$errorMessage = $error;
123
124				if ($error instanceof Exception)
125				{
126					$errorMessage = $error->getMessage();
127				}
128
129				$app->enqueueMessage($errorMessage, 'error');
130			}
131
132			$app->setUserState('com_contact.contact.data', $data);
133
134			$this->setRedirect(JRoute::_('index.php?option=com_contact&view=contact&id=' . $stub . '&catid=' . $contact->catid, false));
135
136			return false;
137		}
138
139		// Validation succeeded, continue with custom handlers
140		$results = $dispatcher->trigger('onValidateContact', array(&$contact, &$data));
141
142		foreach ($results as $result)
143		{
144			if ($result instanceof Exception)
145			{
146				return false;
147			}
148		}
149
150		// Passed Validation: Process the contact plugins to integrate with other applications
151		$dispatcher->trigger('onSubmitContact', array(&$contact, &$data));
152
153		// Send the email
154		$sent = false;
155
156		if (!$contact->params->get('custom_reply'))
157		{
158			$sent = $this->_sendEmail($data, $contact, $contact->params->get('show_email_copy', 0));
159		}
160
161		// Set the success message if it was a success
162		if (!($sent instanceof Exception))
163		{
164			$msg = JText::_('COM_CONTACT_EMAIL_THANKS');
165		}
166		else
167		{
168			$msg = '';
169		}
170
171		// Flush the data from the session
172		$app->setUserState('com_contact.contact.data', null);
173
174		// Redirect if it is set in the parameters, otherwise redirect back to where we came from
175		if ($contact->params->get('redirect'))
176		{
177			$this->setRedirect($contact->params->get('redirect'), $msg);
178		}
179		else
180		{
181			$this->setRedirect(JRoute::_('index.php?option=com_contact&view=contact&id=' . $stub . '&catid=' . $contact->catid, false), $msg);
182		}
183
184		return true;
185	}
186
187	/**
188	 * Method to get a model object, loading it if required.
189	 *
190	 * @param   array     $data               The data to send in the email.
191	 * @param   stdClass  $contact            The user information to send the email to
192	 * @param   boolean   $emailCopyToSender  True to send a copy of the email to the user.
193	 *
194	 * @return  boolean  True on success sending the email, false on failure.
195	 *
196	 * @since   1.6.4
197	 */
198	private function _sendEmail($data, $contact, $emailCopyToSender)
199	{
200		$app = JFactory::getApplication();
201
202		if ($contact->email_to == '' && $contact->user_id != 0)
203		{
204			$contact_user      = JUser::getInstance($contact->user_id);
205			$contact->email_to = $contact_user->get('email');
206		}
207
208		$mailfrom = $app->get('mailfrom');
209		$fromname = $app->get('fromname');
210		$sitename = $app->get('sitename');
211
212		$name    = $data['contact_name'];
213		$email   = JStringPunycode::emailToPunycode($data['contact_email']);
214		$subject = $data['contact_subject'];
215		$body    = $data['contact_message'];
216
217		// Prepare email body
218		$prefix = JText::sprintf('COM_CONTACT_ENQUIRY_TEXT', JUri::base());
219		$body   = $prefix . "\n" . $name . ' <' . $email . '>' . "\r\n\r\n" . stripslashes($body);
220
221		// Load the custom fields
222		if (!empty($data['com_fields']) && $fields = FieldsHelper::getFields('com_contact.mail', $contact, true, $data['com_fields']))
223		{
224			$output = FieldsHelper::render(
225				'com_contact.mail',
226				'fields.render',
227				array(
228					'context' => 'com_contact.mail',
229					'item'    => $contact,
230					'fields'  => $fields,
231				)
232			);
233
234			if ($output)
235			{
236				$body .= "\r\n\r\n" . $output;
237			}
238		}
239
240		$mail = JFactory::getMailer();
241		$mail->addRecipient($contact->email_to);
242		$mail->addReplyTo($email, $name);
243		$mail->setSender(array($mailfrom, $fromname));
244		$mail->setSubject($sitename . ': ' . $subject);
245		$mail->setBody($body);
246		$sent = $mail->Send();
247
248		// If we are supposed to copy the sender, do so.
249
250		// Check whether email copy function activated
251		if ($emailCopyToSender == true && !empty($data['contact_email_copy']))
252		{
253			$copytext    = JText::sprintf('COM_CONTACT_COPYTEXT_OF', $contact->name, $sitename);
254			$copytext    .= "\r\n\r\n" . $body;
255			$copysubject = JText::sprintf('COM_CONTACT_COPYSUBJECT_OF', $subject);
256
257			$mail = JFactory::getMailer();
258			$mail->addRecipient($email);
259			$mail->addReplyTo($email, $name);
260			$mail->setSender(array($mailfrom, $fromname));
261			$mail->setSubject($copysubject);
262			$mail->setBody($copytext);
263			$sent = $mail->Send();
264		}
265
266		return $sent;
267	}
268}
269