AnonSec Shell
Server IP : 54.36.91.62  /  Your IP : 216.73.217.112
Web Server : Apache
System : Linux webm013.cluster127.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64
User : coopiak ( 151928)
PHP Version : 8.3.23
Disable Function : _dyuweyrj4,_dyuweyrj4r,dl
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/coopiak/www/cj79373/plugins/engage/email/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     

Current File : /home/coopiak/www/cj79373/plugins/engage/email/email.php
<?php
/**
 * @package   AkeebaEngage
 * @copyright Copyright (c)2020-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license   GNU General Public License version 3, or later
 */

use Akeeba\Engage\Admin\Model\Comments;
use Akeeba\Engage\Site\Helper\Email;
use Akeeba\Engage\Site\Helper\Meta;
use FOF40\Container\Container;
use FOF40\Model\DataModel\Exception\RecordNotLoaded;
use Joomla\CMS\Access\Access;
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\User\User;

defined('_JEXEC') or die;

class plgEngageEmail extends CMSPlugin
{
	/**
	 * Automatically triggered right after Akeeba Engage saves a NEW comment record to its database table.
	 *
	 * @param   Comments  $comment  The comment that has just been saved.
	 *
	 * @return  void
	 */
	public function onComEngageModelCommentsAfterCreate(Comments $comment): void
	{
		// No emails in CLI, please
		$container = Container::getInstance('com_engage');

		if ($container->platform->isCli())
		{
			return;
		}

		$meta              = Meta::getAssetAccessMeta($comment->asset_id, true);
		$notifyAuthor      = $meta['parameters']->get('comments_notify_author', 1);
		$notifyUsers       = $meta['parameters']->get('comments_notify_users', 1);
		$honorUnsubscribed = true;

		switch ($comment->enabled)
		{
			// Unpublished or Spam: send an email to Comment Managers
			case 0:
			case -3:
				$recipients        = $this->getCommentManagerRecipients();
				$type              = ($comment->enabled == 0) ? 'manage' : 'spam';
				$honorUnsubscribed = false;

				break;

			// Published: notify users taking part in the conversation
			case 1:
				$recipients     = $notifyUsers ? $this->getUserRecipients($comment) : [];
				$type           = 'notify';
				$notifyManagers = $this->params->get('managers_notify', 0) == 1;

				/**
				 * Notify the content author unless he's already being notified as a user
				 */
				if ($notifyAuthor)
				{
					$this->sendEmailMessages('notify_author', $comment, $this->getRecipientsArrayDiff(
						[$meta['author_email'] => $meta['author_name']], $recipients
					));
				}

				if ($notifyManagers)
				{
					/**
					 * Notify managers unless they are being notified EITHER as a user OR as a content author
					 */
					$managerRecipients = $this->getRecipientsArrayDiff($this->getCommentManagerRecipients(), $recipients);

					if ($notifyAuthor)
					{
						$managerRecipients = $this->getRecipientsArrayDiff(
							$this->getCommentManagerRecipients(), [$meta['author_email'] => $meta['author_name']]
						);
					}

					$this->sendEmailMessages('notify_managers', $comment, $managerRecipients);
				}

				break;
		}

		$this->sendEmailMessages($type, $comment, $recipients, $honorUnsubscribed);
	}

	/**
	 * Generates the difference between two recipient arrays. Each array follows the convention email => name
	 *
	 * @param   array  $allRecipients       The array to filter
	 * @param   array  $excludedRecipients  Recipients to remove from $allRecipients
	 *
	 * @return  array  The filtered array
	 */
	protected function getRecipientsArrayDiff(array $allRecipients, array $excludedRecipients): array
	{
		$nonRepliedToEmails = array_diff(array_keys($allRecipients), array_keys($excludedRecipients));

		return array_filter($allRecipients, function ($v, $k) use ($nonRepliedToEmails) {
			return in_array($k, $nonRepliedToEmails);
		}, ARRAY_FILTER_USE_BOTH);
	}

	/**
	 * Returns the ID of all Joomla user groups which are Comment Managers.
	 *
	 * Any user group that has the core.edit.state privilege on the component is considered a Comment Manager.
	 *
	 * @return  array
	 */
	protected function getCommentManagerGroups(): array
	{
		// Get all groups
		$db    = $this->db ?? Factory::getDbo();
		$query = $db->getQuery(true)
			->select([$db->qn('id')])
			->from($db->qn('#__usergroups'));

		$adminGroups = $db->setQuery($query)->loadColumn(0) ?? [];

		return array_filter($adminGroups, function ($group) {
			return
				Access::checkGroup($group, 'core.edit.state', 'com_engage') ||
				Access::checkGroup($group, 'core.edit.state') ||
				Access::checkGroup($group, 'core.admin');
		});
	}

	/**
	 * Returns the email addresses and names of comment managers.
	 *
	 * Only the email addresses of comments managers with Send Email set to Yes will be returned.
	 *
	 * @return  array  User full names keyed by email
	 */
	protected function getCommentManagerRecipients(): array
	{
		$managerGroups = $this->getCommentManagerGroups();

		if (empty($managerGroups))
		{
			return [];
		}

		$ret = [];

		foreach ($managerGroups as $gid)
		{
			$uids = Access::getUsersByGroup($gid);
			array_walk($uids, function ($uid, $k) use (&$ret) {
				$user              = Factory::getUser($uid);
				$ret[$user->email] = $ret[$user->name];
			});
		}

		return $ret;
	}

	/**
	 * Returns the emails and names of the people being replied to with a give comment
	 *
	 * @param   Comments  $comment
	 *
	 * @return  array  An dictionary following the convention email => name
	 */
	protected function getUserRecipients(Comments $comment): array
	{
		// Top level comments don't have reply-to users
		if (empty($comment->getFieldValue('parent_id')))
		{
			return [];
		}

		// Try to load the parent
		try
		{
			/** @var Comments $parent */
			$parent = $comment->tmpInstance();

			$parent->findOrFail($comment->parent_id);
		}
		catch (RecordNotLoaded $e)
		{
			return [];
		}

		$userEmails = [];

		$user                     = $parent->getUser();
		$userEmails[$user->email] = $user->name;

		return $userEmails;
	}

	/**
	 * Returns a list of email addresses which have been unsubscribed from comment notifications for the given Asset ID.
	 *
	 * @param   int  $asset_id  The asset ID for which email addresses have been unsubscribed.
	 *
	 * @return  string[]  A list of email addresses
	 */
	protected function getUnsubscribedEmails(int $asset_id): array
	{
		$db    = $this->db ?? Factory::getDbo();
		$query = $db->getQuery(true)
			->select($db->qn('email'))
			->from($db->qn('#__engage_unsubscribe'))
			->where($db->qn('asset_id') . ' = ' . $db->q($asset_id));

		return $db->setQuery($query)->loadColumn() ?? [];
	}

	/**
	 * Sends emails to a list of users about the given comment
	 *
	 * @param   string    $type               Email type. Must match the `key` column of the email templates table
	 * @param   Comments  $comment            The comment we are sending emails about
	 * @param   array     $recipients         A dictionary of email => name with the recipients
	 * @param   bool      $honorUnsubscribed  Should I honor unsubscribed emails? Default true.
	 *
	 * @return  void
	 */
	protected function sendEmailMessages(string $type, Comments $comment, array $recipients, bool $honorUnsubscribed = true): void
	{
		// Do I have anything to do?
		if (empty($recipients))
		{
			return;
		}

		// Remove users who have already unsubscribed from this content
		if ($honorUnsubscribed)
		{
			$unsubscribedEmails = $this->getUnsubscribedEmails($comment->asset_id);
			$recipients         = array_filter($recipients, function ($v, $k) use ($unsubscribedEmails) {
				return !in_array($k, $unsubscribedEmails);
			}, ARRAY_FILTER_USE_BOTH);
		}

		if (empty($recipients))
		{
			return;
		}

		try
		{
			$mailer = Factory::getMailer();

			$mailer->isHtml(true);
			$mailer->CharSet = 'UTF-8';
		}
		catch (Exception $e)
		{
			return;
		}

		$userIDs = $this->getUserIDsByEmail(array_keys($recipients));

		foreach ($recipients as $email => $name)
		{
			if (isset($userIDs[$email]))
			{
				$thisUser = Factory::getUser($userIDs[$email]);
			}
			else
			{
				$thisUser        = new User();
				$thisUser->name  = $name;
				$thisUser->email = $email;
			}

			$templateInfo = Email::loadEmailTemplateFromDB($type, $thisUser);

			// Dynamic properties. DO NOT use is_null() or empty()
			if (($templateInfo->subject === null) && ($templateInfo->template === null))
			{
				continue;
			}

			$templateInfo = Email::parseTemplate($templateInfo, $comment, $thisUser);

			try
			{
				$myMailer = clone $mailer;
				$myMailer->addRecipient($email, $name);
				$myMailer->setSubject($templateInfo->subject);
				$myMailer->setBody(Email::inlineImages($templateInfo->template, $myMailer));
				$myMailer->Send();
			}
			catch (Exception $e)
			{
				continue;
			}
		}
	}

	/**
	 * Returns the Joomla user IDs given a list of email addresses
	 *
	 * @param   string[]  $emails  The emails to look for
	 *
	 * @return  array  A dictionary of email => ID for any emails that correspond to Joomla user accounts
	 */
	protected function getUserIDsByEmail(array $emails): array
	{
		$db     = $this->db ?? Factory::getDbo();
		$emails = array_map([$db, 'q'], $emails);
		$query  = $db->getQuery(true)
			->select([
				$db->qn('email'),
				$db->qn('id'),
			])
			->from($db->qn('#__users'))
			->where($db->qn('email') . ' IN (' . implode(',', $emails) . ')');

		return $db->setQuery($query)->loadAssocList('email', 'id') ?? [];
	}
}

Anon7 - 2022
AnonSec Team