uawdijnntqw1x1x1
IP : 216.73.217.142
Hostname : localhost.localdomain
Kernel : Linux localhost.localdomain 4.15.0-213-generic #224-Ubuntu SMP Mon Jun 19 13:30:12 UTC 2023 x86_64
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
OS : Linux
PATH:
/
var
/
www
/
consult-e-syn
/
public_html
/
components
/
com_ats
/
Controller
/
NewTicket.php
/
/
<?php /** * @package ats * @copyright Copyright (c)2011-2022 Nicholas K. Dionysopoulos / Akeeba Ltd * @license GNU General Public License version 3, or later */ namespace Akeeba\TicketSystem\Site\Controller; defined('_JEXEC') or die; use Akeeba\TicketSystem\Admin\Controller\Mixin\UserTagsSaveAware; use Akeeba\TicketSystem\Admin\Controller\Ticket; use Akeeba\TicketSystem\Admin\Controller\TraitSaveUserTags; use Akeeba\TicketSystem\Admin\Helper\Credits; use Akeeba\TicketSystem\Admin\Helper\JoomlaUsers; use Akeeba\TicketSystem\Admin\Helper\Permissions; use Akeeba\TicketSystem\Site\Model\Attachments; use Akeeba\TicketSystem\Site\Model\Attempts; use Akeeba\TicketSystem\Site\Model\Categories; use Akeeba\TicketSystem\Site\Model\Posts; use Akeeba\TicketSystem\Site\Model\Tickets; use Exception; use FOF40\Container\Container; use FOF40\Date\Date; use FOF40\View\Exception\AccessForbidden; use Joomla\CMS\Captcha\Captcha as JCaptcha; use Joomla\CMS\Factory as JFactory; use Joomla\CMS\HTML\HTMLHelper as JHtml; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route as JRoute; use Joomla\CMS\Uri\Uri; use Joomla\Registry\Registry; use RuntimeException; class NewTicket extends Ticket { use UserTagsSaveAware; public function __construct(Container $container, array $config = []) { $config['modelName'] = 'Tickets'; $config['cacheableTasks'] = []; parent::__construct($container, $config); } public function execute($task) { $allowed = [ 'default', 'add', 'save', 'getcredits', ]; // Only allow a small subset of available tasks if (!in_array($task, $allowed)) { return false; } if ($task == 'default') { $task = $this->getCrudTask(); } if ($task == 'read') { $task = 'add'; } return parent::execute($task); } /** * ACL checks are deferred to the main save task * * @return bool */ public function onBeforeSave() { return true; } public function save(): void { $this->csrfProtection(); // Fetch page parameters /** @var \JApplicationSite $app */ $app = JFactory::getApplication(); $params = $app->getParams('com_ats'); // Get some basic information about the ticket and the post $ticket = $this->input->get('ticket', [], 'array'); $post = $this->input->get('post', null, 'array', 2); $ticket = is_array($ticket) ? $ticket : []; $ticket['params'] = $this->input->get('params', [], 'array'); $ticket['params'] = is_array($ticket['params']) ? $ticket['params'] : []; // Fetch the category. If the category cannot be loaded we will throw a 403. $category_id = $this->getCategoryID($ticket, $params); $ticket['catid'] = $category_id; if ($category_id <= 0) { throw new AccessForbidden(); } // Can I post to the category? $perms = Permissions::getAclPrivileges($category_id); if (!$perms['core.create']) { throw new AccessForbidden(); } // Am I a manager or a guest? $isManager = Permissions::isManager($category_id); $isGuest = Permissions::getUser()->guest; // Get the email and full name $email = $this->input->getString('email', ''); $fullName = $this->input->getString('name', ''); /** * Save everything in the session - First attempt * * At this stage we are saving the raw form data, before we have had a chance to verify Guest ticket settings. If a * Guest ticket check fails (missing email / fullname or wrong CAPTCHA) we will be redirecting the user to the new ticket * page. If we haven't saved the ticket info in the session the user would have to retype everything. */ if ($isGuest) { $this->saveNewTicketToSession($ticket, $post, $isManager, [ 'ticket_email' => $email, 'ticket_name' => $fullName, ]); } // If I am a guest and the email or full name is empty return an error if ($isGuest) { $email = empty($email) ? '' : trim($email); $fullName = empty($fullName) ? '' : trim($fullName); if (empty($email)) { $this->failSaveWithMessage(Text::_('COM_ATS_NEWTICKET_ERR_GUESTPOST_EMAIL_MISSING'), $category_id); return; } if (empty($fullName)) { $this->failSaveWithMessage(Text::_('COM_ATS_NEWTICKET_ERR_GUESTPOST_FULLNAME_MISSING'), $category_id); return; } } // If a CAPTCHA was used but the solution is incorrect return an error try { if ($isGuest) { $this->isValidCaptcha(); } } catch (RuntimeException $e) { $this->failSaveWithMessage($e->getMessage(), $category_id); return; } // Set up the Created By. Takes into account "Create Post By" and "Guest Post" features. $ticket['created_by'] = $this->getCreatedBy($isManager, $email, $fullName); // I also have to set up Created On since FOF won't set it automatically when Created By is provided. $ticket['created_on'] = Date::getInstance()->toSql(); // Cannot create user, missing parameters if ($ticket['created_by'] === -1) { $this->failSaveWithMessage(Text::_('COM_ATS_NEWTICKET_ERR_GUESTPOST_NOREGISTRATION'), $category_id); return; } // Missing email or full name, go back and retry if ($ticket['created_by'] === false) { // This should have been caught above. If it didn't and we're here return a generic error message. $this->failSaveWithMessage(Text::_('COM_ATS_NEWTICKET_ERR_GUESTPOST_OTHER'), $category_id); return; } // User by that email already exists, redirect to login page if ($ticket['created_by'] === true) { $redirect = $this->getRedirectUrl($category_id, true); $url = 'index.php?option=com_users&view=login&return=' . base64_encode($redirect); $this->setRedirect($url, Text::_('COM_ATS_NEWTICKET_ERR_GUESTPOST_USEREXISTS')); return; } /** * Save everything in the session - Second run. * * This runs no matter if we have a Guest or logged in user. Do NOT delete either of these two calls to * saveNewTicketToSession. They are BOTH required. */ $this->saveNewTicketToSession($ticket, $post, $isManager); // If I'm not allowed to post private tickets force the ticket status to public if (!$perms['ats.private']) { $ticket['public'] = 1; } // Make sure the ticket has a title if (empty($ticket['title'])) { $this->failSaveWithMessage(Text::_('COM_ATS_ERR_NEWTICKET_NOTITLE'), $category_id); return; } // --- Create the ticket /** @var Tickets $model */ $model = $this->getModel()->reset(); // Add custom fields validation $isValid = $model->isValid(); if (!$isValid) { $this->failSaveWithMessage(Text::_('COM_ATS_ERR_NEWTICKET_CUSTOM_FIELDS'), $category_id); return; } // Check available credits $error = $this->checkAvailableCredits($ticket, $post, $isManager); if ($error !== false) { $this->failSaveWithMessage($error, $category_id); return; } // Save the ticket try { $model->save($ticket); } catch (Exception $e) { $this->failSaveWithMessage($e->getMessage(), $category_id); return; } $ats_ticket_id = $model->getId(); $post['ats_ticket_id'] = $ats_ticket_id; // --- Create attachment /** @var Attachments $attachmentModel */ $attachmentModel = $this->container->factory->model('Attachments')->tmpInstance(); $attErrors = []; $filter = $this->container->params->get('unsafe_uploads', 0) ? 'raw' : 'array'; $file = $this->input->files->get('attachedfile', [], $filter); if (isset($file[0]) && ($file[0]['name'] != '') && $perms['ats.attachment']) { [$post['ats_attachment_id'], $attErrors] = $attachmentModel->manageUploads($file); } // --- Create post $post['enabled'] = 1; $status = true; $postError = ''; /** @var Posts $pModel */ $pModel = $this->container->factory->model('posts')->tmpInstance(); /** * Copy the Created By and On values from the ticket. Required for consistency in the Ticket as User (for managers) and * Post as Guest features. */ $post['created_by'] = $ticket['created_by']; $post['created_on'] = $ticket['created_on']; // Save the post (only if we didn't have any error with attachments) if (!$attErrors) { try { $pModel->save($post); } catch (Exception $e) { $postError = $e->getMessage(); $status = false; } } // If I have any attachment, I have to check if they failed if (isset($post['ats_attachment_id'])) { $status = $status && empty($attErrors); } if (!$status) { // Remove the attachments if (isset($post['ats_attachment_id'])) { $attachments = explode(',', $post['ats_attachment_id']); foreach ($attachments as $attachment) { if ($attachment) { $attachmentModel->delete($attachment); } } } // Remove the ticket $model->delete($ats_ticket_id); // Redirect $this->failSaveWithMessage($postError, $category_id); return; } // Update saved attachments with post id if (isset($post['ats_attachment_id'])) { $attachmentModel->updateSavedAttachments($post['ats_attachment_id'], $pModel->ats_post_id); } // Clear session $this->container->platform->unsetSessionVar('ticket_title', 'com_ats.newTicketData'); $this->container->platform->unsetSessionVar('ticket_public', 'com_ats.newTicketData'); $this->container->platform->unsetSessionVar('custom', 'com_ats.newTicketData'); $this->container->platform->unsetSessionVar('post_content', 'com_ats.newTicketData'); $this->container->platform->unsetSessionVar('created_by', 'com_ats.newTicketData'); $this->container->platform->unsetSessionVar('ticket_email', 'com_ats.newTicketData'); $this->container->platform->unsetSessionVar('ticket_fullname', 'com_ats.newTicketData'); // Redirect $url = 'index.php?option=com_ats&view=Tickets&category=' . $category_id . $this->getItemidURLSuffix(); if ($customURL = $this->input->getString('returnurl', '')) { $customURL = base64_decode($customURL); $url = !empty($customURL) ? $customURL : $url; } $this->setRedirect($url, Text::_('COM_ATS_LBL_NEWTICKET_SAVED')); return; } /** * Get the credits required to post a ticket in a given category. * * This method belongs to the Category controller> SInce we're using Joomla! core categories we don't have a * category controller, hence the misplaced method. * * @return void */ public function getcredits() { $catid = $this->input->getInt('catid', 0); $public = $this->input->getInt('public', 1); $priority = $this->input->getInt('priority', 10); $credits = Credits::creditsRequired($catid, true, $public, $priority); echo json_encode(['credits' => $credits]); $this->container->platform->closeApplication(); } /* * Make sure the user is allowed to post in this category */ protected function onAfterSave() { $this->saveUserTags(); $ats_attempt_id = $this->input->getInt('ats_attempt_id'); // Did ATS show up some instant reply, but the user ignored them? if ($ats_attempt_id) { /** @var Attempts $attempt */ $attempt = $this->container->factory->model('Attempts')->tmpInstance(); /** @var Tickets $ticket */ $ticket = $this->getModel(); $attempt->load($ats_attempt_id); $bind['ats_ticket_id'] = $ticket->ats_ticket_id ?? 0; $attempt->save($bind); } return true; } protected function onBeforeAdd() { // Fetch page parameters /** @var \JApplicationSite $app */ $app = JFactory::getApplication(); $params = $app->getParams('com_ats'); $view = $this->getView(); // Set the layout to null to avoid issues from the request or the session $this->layout = null; // Fetch the category $category_id = $this->input->getInt('category', 0); /** @var Categories $catModel */ $catModel = $this->container->factory->model('Categories')->tmpInstance(); if (empty($category_id)) { $category_id = $params->get('category', 0); } if (empty($category_id)) { // No category specified. We'll have to show a landing page. $this->layout = 'landing'; $this->getView()->setLayout('landing'); $this->getView()->categories = $catModel->get(true); return true; } $categories = $catModel->category($category_id)->get(true); /** @var Categories $category */ $category = $categories->first(); if (!$category) { // Category not found, this means that the user is not allowed to access it return false; } // Get ACL permissions $perms = Permissions::getAclPrivileges($category->id); // Can I post to the category? If I can't, throw a 403! if (!$perms['core.create']) { // Am I a guest user? if (Permissions::getUser()->guest) { $returnURL = base64_encode(Uri::getInstance()->toString()); $url = JRoute::_('index.php?option=com_users&view=login&return=' . $returnURL, false); $this->container->platform->redirect($url, '307', Text::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN')); } return false; } // -- If I am a manager allow specifying the created_by user (post as another user) $isManager = Permissions::isManager($category->id); // Load session and push data // @TODO Load everything inside the $cache variable, in the same way we do in Akeeba Subs $custom = $this->container->platform->getSessionVar('custom', [], 'com_ats.newTicketData'); // Make sure that it's an array, so it will be handled correctly by ats plugins (ie customfields) if (!is_array($custom)) { $custom = json_decode($custom, true); } $cache['params'] = $custom; $view->ticket_title = $this->container->platform->getSessionVar('ticket_title', '', 'com_ats.newTicketData'); $view->ticket_public = $this->container->platform->getSessionVar('ticket_public', null, 'com_ats.newTicketData'); $view->post_content = $this->container->platform->getSessionVar('post_content', '', 'com_ats.newTicketData'); $view->ticket_email = $this->container->platform->getSessionVar('ticket_email', '', 'com_ats.newTicketData'); $view->ticket_name = $this->container->platform->getSessionVar('ticket_name', '', 'com_ats.newTicketData'); $view->cache = $cache; $view->captchaPlugin = $this->doINeedCaptcha(); if ($isManager) { $view->created_by = $this->container->platform->getSessionVar('created_by', Permissions::getUser()->id, 'com_ats.newTicketData'); } /** * Um, doing that would reset the form if the user pressed reload. We don't need to do this; the session is unset in the * Controller, anyway, just as soon as we create the new ticket. */ /* $this->container->platform->unsetSessionVar('ticket_title', 'com_ats.newTicketData'); $this->container->platform->unsetSessionVar('ticket_public', 'com_ats.newTicketData'); $this->container->platform->unsetSessionVar('ticket_email', 'com_ats.newTicketData'); $this->container->platform->unsetSessionVar('ticket_name', 'com_ats.newTicketData'); $this->container->platform->unsetSessionVar('post_content', 'com_ats.newTicketData'); */ // Push permissions $view->allow_private = $perms['ats.private']; $view->allow_attachment = $perms['ats.attachment']; // Push page parameters $view->pageparams = $params; // Push category object $view->category = $category; JHtml::_('behavior.keepalive'); return true; } /** * Get the ticket category ID and make sure the category does exist. The category ID is either provided in the form * (in the catid field) or set in the page parameters (e.g. we have a menu item pointing to a specific category) * * @param array $ticket The ticket information * @param Registry $params Page parameters * * @return int The category ID or -1 if it's not found * * @since 2.4.1 */ private function getCategoryID($ticket, $params) { $category_id = 0; if (array_key_exists('catid', $ticket)) { $category_id = $ticket['catid']; } if (empty($category_id)) { $category_id = $params->get('category', 0); } /** @var Categories $catModel */ $catModel = $this->container->factory->model('Categories')->tmpInstance(); $categories = $catModel->category($category_id)->get(true); $category = $categories->first(); if (!$category) { // Category not found, this means that the user is not allowed to access it return -1; } return $category_id; } /** * Save the basic ticket information (everything except custom fields and uploads) into the session. This lets us * show an error without the user losing all of their ticket information. * * @param array $ticket The ticket information * @param array $post The post information * @param bool $isManager Am I a manager? * @param array $extra_data Any additional data to save to the session * * @since 2.4.1 */ private function saveNewTicketToSession(&$ticket, &$post, $isManager, $extra_data = []) { if (!array_key_exists('public', $ticket)) { $ticket['public'] = 1; } if (!array_key_exists('title', $ticket)) { $ticket['title'] = ''; } if (!array_key_exists('content', $post)) { $post['content'] = ''; } if (!array_key_exists('content_html', $post)) { $post['content_html'] = ''; } if (!array_key_exists('created_by', $post)) { $post['created_by'] = null; } $postcontent = empty($post['content']) ? $post['content_html'] : $post['content']; $platform = $this->container->platform; $platform->setSessionVar('ticket_title', $ticket['title'], 'com_ats.newTicketData'); $platform->setSessionVar('ticket_public', $ticket['public'], 'com_ats.newTicketData'); $platform->setSessionVar('custom', $ticket['params'], 'com_ats.newTicketData'); $platform->setSessionVar('post_content', $postcontent, 'com_ats.newTicketData'); if ($isManager) { $platform->setSessionVar('created_by', $ticket['created_by'], 'com_ats.newTicketData'); } if (!empty($extra_data)) { foreach ($extra_data as $k => $v) { $platform->setSessionVar($k, $v, 'com_ats.newTicketData'); } } } /** * Check if the user has the necessary credits required to file the ticket. * * @param array $ticket The ticket information * @param array $post The post information * @param bool $isManager Is this a manager? * * @return bool|string Boolean false or an error message string * * @since 2.4.1 */ private function checkAvailableCredits($ticket, $post, $isManager) { $error = false; if (!$this->container->params->get('showcredits', 0)) { return $error; } $userId = $post['created_by']; // TODO check vs priority $hasCredits = Credits::haveEnoughCredits($userId, $ticket['catid'], true, $ticket['public'], false); if (!$hasCredits) { if ($isManager) { $error = Text::_('COM_ATS_ERR_NEWTICKET_NOT_ENOUGH_CREDITS_USER'); } else { $error = Text::_('COM_ATS_ERR_NEWTICKET_NOT_ENOUGH_CREDITS'); } } return $error; } /** * Fail the save operation with the message. Redirects back to the ticket submission page. If $error is empty a * redirection without a message is performed. * * @param string $error Message to show to the user. * @param int $category_id ATS category ID * @param bool $showCustomFieldsValidation Should I display the custom fields validation status when I * return? * * * @since 2.4.1 */ private function failSaveWithMessage($error, $category_id, $showCustomFieldsValidation = true) { $url = $this->getRedirectUrl($category_id, $showCustomFieldsValidation); if (empty($error)) { $this->setRedirect($url); return; } $this->setRedirect($url, $error, 'error'); } /** * Get the appropriate Created By user ID. * * If the ticket is submitted by a manager and there's a created_by form field (Post As Another User) we use that. * If not, or if the ticket is filed by any other registered user we return the currently logged in user's ID. * If it's a Guest we try to create a user using the email and full name provided and return that user ID. This * could fail. If user registration is disabled we return false. If the email or full name is missing we return -1. * If there is another user by that email we return true because the user needs to log in instead. * * @param bool $isManager Is this being filed by a Manager (support staff)? * * @return int|bool User ID, -1 (cannot create user), false (no email / full name provided) or true (user by that * email already exists) * * @since 2.4.1 */ private function getCreatedBy($isManager, $email, $fullName) { // Get a reference to the currently logged in user $user = Permissions::getUser(); // If I am a manager, am I posting as another user? This has priority over anything else. if ($isManager) { $custom_created_by = $this->input->getInt('created_by', 0); if ($custom_created_by) { return $custom_created_by; } } // If I am any other logged in user return the user ID if (!$user->guest) { return $user->id; } // If I'm here I am a guest. If there is no email address in the request return boolean false if (empty($email) || empty($fullName)) { return false; } // If I have an email, is there a user already assigned to it? If so, return boolean true $ju = new JoomlaUsers($this->container); $userId = $ju->getUserIdByEmail($email); if ($userId) { return true; } // No such user exists. Create a new user and send the user creation email etc. try { $forceActivate = $this->container->params->get('forceGuestActivation', 0); [, $userId] = $ju->createUser($email, $fullName, $forceActivate); } catch (Exception $e) { return -1; } return $userId; } /** * Used for Guest submissions. Checks if the CAPTCHA is enabled for Guest posts and checks if it's been filled in. * * @throws \RuntimeException * @since 2.4.1 * */ private function isValidCaptcha() { $captchaPlugin = $this->doINeedCaptcha(); if ($captchaPlugin === false) { return; } // Validate the CAPTCHA solution $code = $this->input->get('captcha', null, 'raw'); $captcha = JCaptcha::getInstance($captchaPlugin, ['namespace' => 'com_ats_newTicket']); $captcha->checkAnswer($code); } /** * Gets the redirection URL which gets us back to the ticket submission page * * @param int $category_id ATS category ID * @param bool $showCustomFieldsValidation Should I display the custom fields validation status when I return? * * @return string The URL * * @since 2.4.1 */ private function getRedirectUrl($category_id, $showCustomFieldsValidation) { $url = 'index.php?option=com_ats&view=NewTicket&category=' . $category_id; if ($showCustomFieldsValidation) { $url .= '&formsubmit=1'; } $url .= $this->getItemidURLSuffix(); $url = JRoute::_($url, false); return $url; } /** * * @return bool */ private function doINeedCaptcha() { // Do I even need to check for a CAPTCHA? $needsCaptcha = $this->container->params->get('showGuestCAPTCHA', 1) == 1; if (!$needsCaptcha) { return false; } // Get the site-wide CAPTCHA plugin $app = JFactory::getApplication(); $captchaPlugin = $app->get('captcha'); if ($this->container->platform->isFrontend()) { /** @var \JApplicationSite $app */ $captchaPlugin = $app->getParams()->get('captcha', $captchaPlugin); } // No CAPTCHA plugin is activated? if (empty($captchaPlugin) || ($captchaPlugin == 'none')) { return false; } return $captchaPlugin; } }
/var/www/consult-e-syn/public_html/components/com_ats/Controller/NewTicket.php