Your IP : 216.73.216.182


Current Path : /var/www/html/administrator/components/com_komento/includes/easysocial/
Upload File :
Current File : /var/www/html/administrator/components/com_komento/includes/easysocial/easysocial.php

<?php
/**
* @package		Komento
* @copyright	Copyright (C) Stack Ideas Sdn Bhd. All rights reserved.
* @license		GNU/GPL, see LICENSE.php
* Komento is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See COPYRIGHT.php for copyright notices and details.
*/
defined('_JEXEC') or die('Unauthorized Access');

class KomentoEasySocial
{
	private $file = null;

	public function __construct()
	{
		FH::loadLanguage('com_komento');

		$this->file = JPATH_ADMINISTRATOR . '/components/com_easysocial/includes/easysocial.php';
		$this->config = KT::config();
		$this->my = JFactory::getUser();
		$this->doc = JFactory::getDocument();
	}

	/**
	 * Determines if EasySocial is installed on the site.
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function exists()
	{
		static $loaded = false;

		if ($loaded) {
			return true;
		}

		if (!JFile::exists($this->file)) {
			return false;
		}

		require_once($this->file);

		$loaded = true;

		return true;
	}

	/**
	 * Initializes EasySocial
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function init()
	{
		static $loaded = null;

		if (!is_null($loaded)) {
			return $loaded;
		}

		if (!$this->exists() || $this->doc->getType() != 'html') {
			$loaded = false;

			return false;
		}

		// Prior to EasySocial 2.0
		if ($this->isLegacy()) {
			$doc = ES::document();
			$doc->init();

			$page = ES::page();
			$page->processScripts();
		} else {
			ES::initialize();
		}

		// Load EasySocial's language files
		ES::language()->loadSite();

		$loaded = true;

		return $loaded;
	}

	/**
	 * Determines if this is EasySocial prior to 2.x
	 *
	 * @since	2.0.11
	 * @access	public
	 */
	public function isLegacy()
	{
		if (!$this->exists()) {
			return;
		}

		// Get the current version.
		$local = ES::getLocalVersion();

		$legacy = version_compare($local, '2.0.0') == -1 ? true : false;

		return $legacy;
	}

	/**
	 * Get the Komento Comments app table object
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function getApp()
	{
		static $app = null;

		if (!isset($app)) {

			$options = ['element' => 'comments', 'type' => 'apps', 'group' => 'user'];

			$table = ES::table('App');
			$state = $table->load($options);

			if (!$state) {
				$app = false;
			} else {
				$app = $table;
			}
		}

		return $app;
	}

	/**
	 * Assign badge to a user
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function assignBadge($action, KomentoComment $comment)
	{
		if (!$this->exists() || !$this->config->get('enable_easysocial_badges')) {
			return false;
		}

		$badge = ES::badges();

		if ($action == 'comment') {
			$badge->log('com_komento', 'komento.add.comment', $comment->created_by, JText::_('COM_KOMENTO_EASYSOCIAL_BADGES_ADD_COMMENTS_MESSAGE'));
		}

		if ($action == 'reply') {
			$badge->log('com_komento', 'komento.reply.comment', $comment->created_by, JText::_('COM_KOMENTO_EASYSOCIAL_BADGES_REPLY_COMMENTS_MESSAGE'));
		}

		if ($action == 'like') {
			$badge->log('com_komento', 'komento.like.comment', $this->my->id, JText::_('COM_KOMENTO_EASYSOCIAL_BADGES_LIKE_COMMENTS_MESSAGE'));
		}

		if ($action == 'report') {
			$badge->log('com_komento', 'komento.report.comment', $this->my->id, JText::_('COM_KOMENTO_EASYSOCIAL_BADGES_REPORT_COMMENTS_MESSAGE'));
		}

		if ($action == 'upload') {
			$badge->log('com_komento', 'komento.upload.attachments', $comment->created_by, JText::_('COM_KOMENTO_EASYSOCIAL_BADGES_UPLOAD_COMMENTS_MESSAGE'));
		}

		return true;
	}

	/**
	 * Assign points for a particular activity
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function assignPoints($action, KomentoComment $comment, $actor)
	{
		if (!$this->exists() || !$this->config->get('enable_easysocial_points')) {
			return false;
		}

		$author = ES::user($comment->created_by);
		$points	= ES::points();

		// Get applications author of the item
		$app = $comment->getApplication();
		$authorId = $app->getAuthorId();

		if ($action == 'comment') {
			// Assign points for the article author
			$points->assign('komento.add.comment.article.author', 'com_komento', $authorId);
		}

		if ($action == 'comment' || $action == 'reply') {
			$rule = 'komento.add.comment';

			if ($action == 'reply') {
				$rule = 'komento.reply.comment';
			}

			if (method_exists($points, 'getParams')) {
				$params	= $points->getParams($rule, 'com_komento');
				$length	= FCJString::strlen($comment->comment);
				$state 	= false;

				if ($params && $params->get('min')) {
					$min = isset($params->get('min')->value) ? $params->get('min')->value : $params->get('min')->default;
					
					if ($length > $min || $min == 0) {
						$points->assign($rule, 'com_komento', $comment->created_by);
					}
				} else {
					$points->assign($rule, 'com_komento', $comment->created_by);
				}
			} else {
				$points->assign($rule, 'com_komento', $comment->created_by);
			}
		}

		if ($action == 'like') {
			$points->assign('komento.like.comment', 'com_komento', $actor->id);
			$points->assign('komento.comment.liked', 'com_komento', $comment->created_by);
		}

		if ($action == 'unlike') {
			$points->assign('komento.unlike.comment', 'com_komento', $actor->id);
			$points->assign('komento.comment.unliked', 'com_komento', $comment->created_by);
		}

		if ($action == 'report') {
			$points->assign('komento.report.comment', 'com_komento', $actor->id);
			$points->assign('komento.comment.reported', 'com_komento', $comment->created_by);
		}

		if ($action == 'unreport') {
			$points->assign('komento.unreport.comment', 'com_komento', $actor->id);
			$points->assign('komento.comment.unreported', 'com_komento', $comment->created_by);
		}

		if ($action == 'stick') {
			$points->assign('komento.comment.sticked', 'com_komento', $comment->created_by);
		}

		if ($action == 'unstick') {
			$points->assign('komento.comment.unsticked', 'com_komento', $comment->created_by);
		}

		if ($action == 'remove') {
			$points->assign('komento.comment.removed', 'com_komento', $comment->created_by);
			$points->assign('komento.remove.comment.article.author', 'com_komento', $authorId);
		}

		if ($action == 'upload') {
			$points->assign('komento.upload.attachments', 'com_komento', $comment->created_by);
		}

		return true;
	}

	/**
	 * Creates a new stream for new comment post
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function createStream($action, &$comment)
	{
		if (!$this->exists()) {
			return false;
		}

		// Make sure this is a new comment
		if ($action == 'comment' && !$comment->isNew()) {
			return false;
		}

		$my = ES::user();

		$stream = ES::stream();
		$template = $stream->getTemplate();
		$template->setContext($comment->id, 'komento');
		$template->setVerb($action);
		$template->setPublicStream('core.view');
		$template->setType('full');

		if ($action == 'like') {

			$options = ['actor_id' => $my->id, 'actor_type' => SOCIAL_TYPE_USER, 'context_type' => 'komento', 'context_id' => $comment->id, 'verb' => 'like'];

			$table = ES::table('StreamItem');
			$state = $table->load($options);

			if ($state) {
				return false;
			}

			$template->setActor($my->id, SOCIAL_TYPE_USER);
			$template->setType('mini');
		}

		if ($action == 'comment') {
			$template->setActor($comment->created_by, SOCIAL_TYPE_USER);
		}

		if ($action == 'reply') {
			$template->setActor($comment->created_by, SOCIAL_TYPE_USER);
		}

		$state = $stream->add($template);

		if ($state) {
			$table = ES::table('StreamItem');
			$table->load(['actor_id' => $my->id, 'actor_type' => SOCIAL_TYPE_USER, 'context_type' => 'komento', 'context_id' => $comment->id, 'verb' => 'comment']);

			$params = $comment->getParams();
			$data = $params->get('social');

			if (!$data) {
				$data = new stdClass();
			}

			$data->stream = $table->uid;

			$params->set('social', $data);
			$comment->params = $params->toString();

			$comment->save(['processPostSave' => false, 'ignorePreSave' => true]);
		}

		return $state;
	}

	/**
	 * Synchronizes comments between Komento and EasySocial
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function syncComments($action, KomentoComment $comment)
	{
		if (!$this->config->get('enable_easysocial_sync_comment')) {
			return false;
		}

		$params = $comment->getParams();
		$social = $params->get('social', '');

		if ($action === 'reply') {

			if (empty($social)) {
				$this->createComment($comment, $social);
			} else {
				$this->editComment($comment, $social);
			}
			
		}

		if ($action === 'remove' && $this->config->get('enable_easysocial_sync_comment')) {
			$this->removeComment($comment);
		}
	}

	/**
	 * When synchronizing comments is enabled we need to inject the comment
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function editComment(&$comment, $socialParams = '')
	{
		if (!$this->exists()) {
			return false;
		}

		$parent = $comment->getParent();
		$parentParams = $parent->getParams();
		$social = $parentParams->get('social');

		$socialComment = ES::table('Comments');

		if (isset($socialParams->target)) {
			$socialComment->load($socialParams->target);
			$socialComment->comment = $comment->comment;
			$socialComment->store();
		}

		if (isset($socialParams->source)) {
			$socialComment->load($socialParams->source);
			$socialComment->comment = $comment->comment;
			$socialComment->store();
		}
	}

	/**
	 * When synchronizing comments is enabled we need to inject the comment
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function createComment(&$comment, $socialParams = '')
	{
		if (!$this->exists()) {
			return false;
		}

		$parent = $comment->getParent();
		$parentParams = $parent->getParams();
		$social = $parentParams->get('social');

		// If the comment is not linked to a stream item, we can't synchronize the comment
		if (empty($social->stream)) {
			return false;
		}

		$socialComment = ES::table('Comments');
		$streamId = $social->stream;

		// If there is a target, means this is replying
		if (isset($social->target) && $social->target) {
			$socialComment->parent = $social->target;
		}

		// Create EasySocial comments
		$socialComment->element = 'komento.user.create';
		$socialComment->created_by = $comment->created_by;
		$socialComment->comment = $comment->comment;
		$socialComment->uid = $streamId;
		$socialComment->stream_id = $streamId;
		$socialCommentParams = new JRegistry();
		$socialCommentParams->set('url', ESR::stream(['layout' => 'item', 'id' => $streamId]));
		$socialCommentParams->set('komento', (object) ['source' => $comment->id]);

		$socialComment->params = $socialCommentParams->toString();

		$state = $socialComment->store();

		// Once we stored the comments on EasySocial, we now need to link
		if ($state) {
			$social->target = $socialComment->id;

			$parentParams->set('social', $social);

			$comment->params = $parentParams->toString();

			$comment->save(['processPostSave' => false]);
		}
	}

	/**
	 * Removes a comment on easysocial
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function removeComment(KomentoComment $comment)
	{
		if (!$this->exists()) {
			return false;
		}

		// Try to delete any existing stream item from EasySocial
		ES::stream()->delete($comment->id, 'komento', $comment->created_by);

		$params = $comment->getParams();
		$social = $params->get('social', '');

		if (!empty($social->target)) {
			$commentTable = ES::table('comments');
			$state = $commentTable->load($social->target);

			if ($state) {
				$commentTable->delete();
			}
		}

		if (!empty($social->source)) {
			$commentTable = ES::table('comments');
			$state = $commentTable->load($social->source);

			if ($state) {
				$commentTable->delete();
			}
		}
	}

	/**
	 * Synchronizes the likes between a komento comment item and easysocial stream item
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function syncLikes($action, KomentoComment $comment)
	{
		if (!$this->config->get('enable_easysocial_sync_like')) {
			return false;
		}

		if ($action == 'like') {
			$this->createLikes($comment);
		}

		if ($action === 'unlike') {
			$this->removeLike($comment);
		}
	}

	/**
	 * Creates a like record for the stream item in EasySocial
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function createLikes(KomentoComment $comment)
	{
		if (!$this->exists()) {
			return false;
		}

		$params = $comment->getParams();
		$social = $params->get('social');

		if (!$social && !$social->stream) {
			return false;
		}

		$options = [
			'type' => 'komento.user.create', 
			'uid' => $social->stream, 
			'created_by' => $this->my->id
		];

		$like = ES::table('Likes');
		$exists = $like->load($options);

		if (!$exists) {
			$like->type = 'komento.user.create';
			$like->uid = $social->stream;
			$like->created_by = $this->my->id;
			$like->created = JFactory::getDate()->toSql();
			$like->stream_id = $social->stream;
			$like->store();
		}
	}

	/**
	 * Removes the likes record from EasySocial when a person unlikes the comment
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function removeLike(KomentoComment $comment)
	{
		if (!$this->exists()) {
			return false;
		}

		$params = $comment->getParams();
		$social = $params->get('social');

		if (!$social && !$social->stream) {
			return false;
		}

		$options = [
			'type' => 'komento.user.create', 
			'uid' => $social->stream, 
			'created_by' => $this->my->id
		];

		$like = ES::table('Likes');
		$exists = $like->load($options);

		if ($exists) {
			$like->delete();

			// Try to delete any existing stream item from EasySocial
			ES::stream()->delete($comment->id, 'komento', $comment->created_by, 'like');
		}
	}

	/**
	 * Notifies a list of names
	 *
	 * @since	4.0
	 * @access	public
	 */
	public function notifyNames($names, $comment)
	{
		$app = $comment->getApplication();

		$options = [
			'uid' => $comment->id,
			'actor_id' => $this->my->id,
			'type' => 'komento',
			'url' => $comment->getPermalink(),
			'contentTitle' => $app->getContentTitle(),
			'owner' => $comment->created_by
		];

		$recipients = [];

		foreach ($names as $recipient) {
			$recipients[] = $recipient->id;
		}

		ES::notify('komento.mentions', $recipients, false, $options);
	}

	/**
	 * Notifies a list of users
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function notify($action, $comment)
	{
		if (!$this->exists() || !$this->config->get('notification_es_event_new_' . $action)) {
			return false;
		}

		$maxUserThreshold = 30;

		//NOTE: usergroup alwaya at the last.
		$targets = [];

		if ($action == 'comment') {
			$targets = ['author', 'participant', 'usergroup'];
		}

		if ($action == 'reply') {
			$targets = ['parent', 'author', 'participant', 'usergroup'];
		}

		if ($action == 'like') {
			$targets = ['owner', 'usergroup'];
		}

		// Nothing to notify
		if (!$targets) {
			return false;
		}

		$app = $comment->getApplication();

		$systemOptions = [
			'uid' => $comment->id,
			'actor_id' => $this->my->id,
			'type' => 'komento',
			'url' => $comment->getPermalink(),
			'contentTitle' => $app->getContentTitle(),
			'owner' => $comment->created_by
		];

		$socialApp = $this->getApp();

		if ($socialApp) {
			$systemOptions['app_id'] = $socialApp->id;
		}

		$tobeNotify = [];

		// We always do not want action user to get notified
		$tobeNotify[] = $this->my->id;
		$exludeIds[] = $this->my->id;

		$hasUserGroup = in_array('usergroup', $targets);

		if ($hasUserGroup) {
			// remove the last segment, which is usergroup. we will process usergroup differently.
			array_pop($targets);
		}

		// group the users
		foreach ($targets as $target) {
			$users = array_diff($this->getNotificationTarget($target, $action, $comment), $exludeIds);

			if ($target != 'participant') {
				$systemOptions['target'] = $target;
				ES::notify('komento.' . $action, $users, false, $systemOptions);
				$exludeIds = array_merge($exludeIds, $users);

			} else {
				$tobeNotify = $users;
				$exludeIds = array_merge($exludeIds, $users);
			}

		}

		if ($tobeNotify) {
			// if we reach here, means we are processing participients.
			$systemOptions['target'] = 'participant';

			// if the users is not exceeded the max, then we use normal way to send the notification to ES.
			// #233
			if (count($tobeNotify) <= $maxUserThreshold) {
				ES::notify('komento.' . $action, $tobeNotify, false, $systemOptions);
			} else {
				// we send as batch
				$this->notifyUsers('komento.' . $action, $tobeNotify, 'user', $systemOptions);
			}

			$exludeIds = array_merge($exludeIds, $tobeNotify);
		}

		// now we process the user groups as batch. #233
		if ($hasUserGroup) {
			$systemOptions['target'] = 'usergroup';

			// get the user group ids.
			$gids = $this->getNotificationTarget('usergroup', $action, $comment);

			if ($gids) {
				$this->notifyUsers('komento.' . $action, $gids, 'usergroup', $systemOptions, $exludeIds);
			}
		}
	}

	/**
	 * Notifies a list of users
	 *
	 * @since	3.0.11
	 * @access	public
	 */
	public function notifyUsers($rules, $recipients, $recipientType, $systemOptions, $exclude = [])
	{
		$model = KT::model('easysocial');
		$model->notifyUsers($rules, $recipients, $recipientType, $systemOptions, $exclude);
	}

	/**
	 *
	 * @since	3.0
	 * @access	public
	 */
	public function getNotificationTarget($target, $action, $comment)
	{
		$ids = [];

		switch($target)
		{
			case 'usergroup':
				$gids = $this->config->get('notification_es_to_usergroup_' . $action);

				if (!empty($gids)) {
					if (!is_array($gids)) {
						$gids = explode(',', $gids);
					}

					$ids = $gids;
				}
			break;

			case 'author':

				if ($this->config->get('notification_es_to_author')) {
					$application = KT::loadApplication($comment->component)->load($comment->cid);

					$author = $application->getAuthorId();

					if (!empty($author)) {
						$ids = [$author];
					}
				}
			break;

			case 'parent':
				if (!empty($comment->parent_id)) {
					$parent = KT::getTable('comments');
					$state = $parent->load($comment->parent_id);

					if ($state && !empty($parent->created_by)) {
						$ids = [$parent->created_by];
					}
				}
			break;

			case 'owner':
				if (!empty($comment->created_by)) {
					$ids = [$comment->created_by];
				}
			break;

			case 'participant':
				if ($this->config->get('notification_es_to_participant')) {
					$options = [
						'component' => $comment->component,
						'cid' => $comment->cid,
						'noguest' => true,
						'state' => 1
					];

					$model = KT::model('comments');
					$ids = $model->getUsers($options);
				}
			break;
		}

		return $ids;
	}
}