<?php

/* ======================================================================*\
  || #################################################################### ||
  || # vBulletin 5.0.0 Beta 10
  || # ---------------------------------------------------------------- # ||
  || # Copyright �2000-2012 vBulletin Solutions Inc. All Rights Reserved. ||
  || # This file may not be redistributed in whole or significant part. # ||
  || # ---------------- VBULLETIN IS NOT FREE SOFTWARE ---------------- # ||
  || # http://www.vbulletin.com | http://www.vbulletin.com/license.html # ||
  || #################################################################### ||
  \*====================================================================== */

class vB5_Frontend_Controller_Activity extends vB5_Frontend_Controller
{
	public function __construct()
	{
		parent::__construct();
	}

	protected function fetchChannelNodes($parent, $page, $perpage, $depth = 3, $contentype = 0, $options = false)
	{
		$api = Api_InterfaceAbstract::instance();
		$optionsArray = array();
		if (!$contentype)
		{
			$contentype = $api->callApi('contenttype', 'fetchContentTypeIdFromClass', array('Channel'));
		}

		$params = array(
			'parentid'		=> $parent,
			'page'			=> $page,
			'perpage'		=> $perpage,
			'depth'			=> $depth,
			'contenttypeid'		=> $contentype,
			'options'		=> $options
		);
		return $api->callApi('node', 'listNodeFullContent', $params);
	}

	public function actionGet()
	{
		$filters = $_POST['filters'];
		$search = array();
		$stickySearchOptions = array('sticky_only' => 1);
		$stickynodes = array();
		if (isset($filters['q']) AND trim($filters['q']) != '')
		{
			$search['keywords'] = $filters['q'];
		}
		else
		{
			$filters['q'] = false;
		}

		if (!empty($filters['exclude_type']))
		{
			$search['exclude_type'] = $filters['exclude_type'];
		}

		if (!empty($filters['userid']))
		{
			$search['author'] = $filters['userid'];
		}

		if (!empty($filters['filter_prefix']))
		{
			if ($filters['filter_prefix'] == '-1')
			{
				$search['prefix'] = '';
			}
			else
			{
				$search['prefix'] = $filters['filter_prefix'];
			}
		}

		if (isset($filters['nodeid']) AND intval($filters['nodeid']) > 0)
		{
			$search['channel'] = $filters['nodeid'];
			$stickySearchOptions['channel'] = $filters['nodeid'];
		}
		switch ($filters['view'])
		{
			case 'topic':
			case 'activity_topic':
				$search['view'] = vB_Api_Search::FILTER_VIEW_TOPIC;
				$search['depth'] = 1;
				if (empty($filters['pagenum']) OR $filters['pagenum'] == 1 OR vB::getDatastore()->getOption('showstickies'))
				{
					$stickynodes = Api_InterfaceAbstract::instance()->callApi('search', 'getInitialResults', array($stickySearchOptions));
				}
				$search['exclude_sticky'] = true;
				break;
			case 'channel': //Channel view is the same with Activity view except that Channel view's search scope is within that channel only as specified by the channel nodeid in the 'channel' filter
				$search['include_sticky'] = true;
			case 'activity':
				$search['view'] = vB_Api_Search::FILTER_VIEW_ACTIVITY;
				break;
			case 'stream':
				$search['view'] = vB_Api_Search::FILTER_VIEW_CONVERSATION_STREAM;
				$search['include_starter'] = true;
				$search['depth'] = 2;
				break;
			case 'thread':
				$search['view'] = vB_Api_Search::FILTER_VIEW_CONVERSATION_THREAD;
				$search['include_sticky'] = true;
				$search['include_starter'] = true;
				$search['depth'] = 1;
				if ($filters['q'])
				{
					$search['view'] = vB_Api_Search::FILTER_VIEW_CONVERSATION_THREAD_SEARCH;
				}
			break;
		}

		if (isset($filters[vB_Api_Node::FILTER_DEPTH]))
		{
			$search['depth'] = intval($filters[vB_Api_Node::FILTER_DEPTH]);
		}

		if (isset($filters[vB_Api_Node::FILTER_SORT]))
		{
			switch($filters[vB_Api_Node::FILTER_SORT])
			{
				case vB_Api_Node::FILTER_SORTFEATURED:
					$search['featured'] = 1;
					break;
				case vB_Api_Node::FILTER_SORTPOPULAR:
					$search['sort']['votes'] = 'desc';
					break;
				case vB_Api_Node::FILTER_SORTOLDEST:
					if (isset($filters['view']) AND $filters['view'] == 'topic')
					{
						$search['sort']['lastcontent'] = 'asc';
					}
					else
					{
						$search['sort']['publishdate'] = 'asc';
					}
					break;
				case vB_Api_Node::FILTER_SORTMOSTRECENT:
				default:
					if (isset($filters['view']) AND $filters['view'] == 'topic')
					{
						$search['sort']['lastcontent'] = 'desc';
					}
					else
					{
						$search['sort']['publishdate'] = 'desc';
					}
					break;
			}
		}
		elseif ($filters['view'] == 'thread' OR $filters['view'] == 'activity_topic')
		{
			$search['sort']['publishdate'] = 'asc';
		}
		elseif ($filters['view'] == 'topic')
		{
			$search['sort']['lastcontent'] = 'desc';
		}

		if (isset($filters['checkSince']) AND is_numeric($filters['checkSince']))
		{
 			$search['date']['from'] = $filters['checkSince'] + 1;
		}
		elseif (isset($filters[vB_Api_Node::FILTER_TIME]))
		{
			switch($filters[vB_Api_Node::FILTER_TIME])
			{
				case vB_Api_Node::FILTER_LASTDAY:
					$search['date']['from'] = vB_Api_Search::FILTER_LASTDAY;
					break;
				case vB_Api_Node::FILTER_LASTWEEK:
					$search['date']['from'] = vB_Api_Search::FILTER_LASTWEEK;
					break;
				case vB_Api_Node::FILTER_LASTMONTH:
					$search['date']['from'] = vB_Api_Search::FILTER_LASTMONTH;
					break;
				case vB_Api_Node::FILTER_ALLTIME:
				default:
					break;
			}
		}

		if (isset($filters[vB_Api_Node::FILTER_SHOW]) AND strcasecmp($filters[vB_Api_Node::FILTER_SHOW], vB_Api_Node::FILTER_SHOWALL) != 0)
		{
			$search['type'] = $filters[vB_Api_Node::FILTER_SHOW];
		}

		$search['ignore_protected'] = 1;

		$nodes = Api_InterfaceAbstract::instance()->callApi('search', 'getInitialResults', array(
				$search,
				empty($filters['per-page']) ? false : $filters['per-page'],
				empty($filters['pagenum']) ? false : $filters['pagenum'],
				true
		));
		switch($filters['view'])
		{
			case 'channel':
				$result = $this->processActivityStream($nodes, false, $filters['view']);
				break;
			case 'activity_topic':
			case 'activity':
				$result = $this->processActivityStream($nodes, true, $filters['view']);
				break;
			case 'thread':
			case 'stream':
				$result = $this->processConversationDetail($nodes, $filters);
				break;
			case 'topic':
				$result = $this->processTopics($nodes, $stickynodes);
				break;
		}

		if (!$result['lastDate'])
		{
			$result['lastDate'] = time();
		}
		$this->sendAsJson($result);
	}

	public function actionForumlist()
	{
		$templateName = (isset($_POST['template'])) ? $_POST['template'] : '';
		if (empty($templateName))
		{
			return;
		}

		$parentid = (isset($_POST['parentid']) AND intval($_POST['parentid']) > 0) ? intval($_POST['parentid']) : -1;
		$depth = (isset($_POST['depth']) AND intval($_POST['depth']) > 0) ? intval($_POST['depth']) : 3;

		$channels = $channelHierarchy = array();
		$api = Api_InterfaceAbstract::instance();
		$options = array('sort' => array('displayorder' => 'ASC', 'title' => 'ASC'));

		$roots = $api->callApi('content_channel', 'fetchTopLevelChannelIds');
		if ($parentid == -1)
		{
			$parentid = $roots['forum'];
		}

		$nodes = $this->fetchChannelNodes($parentid, 1, 100, $depth, 0, $options);

		$templater = new vB5_Template($templateName);

		if (!empty($nodes) AND empty($nodes['errors']))
		{
			foreach ($nodes AS $node)
			{
				$channels[$node['nodeid']] = array(
					'nodeid' 		=> $node['nodeid'],
					'routeid' 		=> $node['routeid'],
					'title'			=> $node['title'],
					'description'	=> $node['description'],
					'parentid' 		=> $node['parentid'],
					'textcount'		=> $node['textcount'],
					'totalcount'	=> $node['totalcount'],
					'viewing'		=> 0, //@TODO: is the number of 'viewing' users implemented in api?
					'lastcontent' 	=> array(
						'nodeid'	=> $node['lastcontentid'],
						'title'		=> '',
						'authorname'=> $node['lastcontentauthor'],
						'userid'	=> $node['lastauthorid'],
						'starter'	=> array(),
					),
					'readtime' 		=> isset($node['readtime']) ? $node['readtime'] : null,
					'is_new'		=> empty($node['readtime']) OR (!empty($node['lastcontent']) AND $node['lastcontent'] > $node['readtime']),
					'subchannels' 	=> array(),
					'category' 	    => $node['content']['category'],
					'displayorder'  => $node['displayorder'],
				);

				if (!empty($node['readtime']))
				{
					$channels[$node['nodeid']]['readtime'] = $node['readtime'];

				}
			}

			foreach ($channels as $channel)
			{
				$nodeId = $channel['nodeid'];
				$parentId = $channel['parentid'];

				if ($channel['lastcontent']['nodeid'] > 0)
				{
					$node = $api->callApi('node', 'getFullContentforNodes', array(array($channel['lastcontent']['nodeid'])));

					if (empty($node['errors']))
					{
						if (is_array($node) )
						{
							$node = array_pop($node);
						}
						$channels[$nodeId]['lastcontent']['title'] = $node['content']['title'];
						$channels[$nodeId]['lastcontent']['created'] = $node['content']['created'];
						$channels[$nodeId]['lastcontent']['parentid'] = $node['content']['parentid'];
						$channels[$nodeId]['lastcontent']['starter']['nodeid'] = $node['content']['starter'];
						$channels[$nodeId]['lastcontent']['starter']['routeid'] = $node['content']['starterroute'];
						$channels[$nodeId]['lastcontent']['starter']['title'] = $node['content']['startertitle'];
						if (!empty($node['prefixid']))
						{
							$channels[$nodeId]['lastcontent']['starter']['prefixid'] = $node['prefixid'];
						}
						if (!empty($node['prefix_rich']))
						{
							$channels[$nodeId]['lastcontent']['starter']['prefix_rich'] = $node['prefix_rich'];
						}
						if (!empty($node['prefix_plain']))
						{
							$channels[$nodeId]['lastcontent']['starter']['prefix_plain'] = $node['prefix_plain'];
						}
					}
				}

				if (isset($channels[$parentId]))
				{
					// assign by reference, so subchannels can be filled in later
					$channels[$parentId]['subchannels'][$nodeId] =& $channels[$nodeId];
				}
				else
				{
					// assign by reference, so subchannels can be filled in later
					$channelHierarchy[$nodeId] =& $channels[$nodeId];
				}
			}

			if ($parentid > 1)
			{
				$cList =& $channelHierarchy;
			}
			else
			{
				$filter = array($roots['forum'] => 1);
				$cList = array_intersect_key($channelHierarchy, $filter);
			}

			$templater->register('channels', $cList);
			$templater->register('root', $parentid);
		}
		else
		{
			$templater->register('channels', $nodes);
		}

		$results = $templater->render();
		echo $results;
	}

	public function actionBlogFilter()
	{
	}

	public function actionBloglist()
	{
		$channels = $channelHierarchy = array();
		$api = Api_InterfaceAbstract::instance();
		$blogChannel = $api->callApi('blog', 'getBlogChannel', array());
		$nodes = $this->fetchChannelNodes(9, 1, 100);
		$templater = new vB5_Template('display_Forums');

		if (!empty($nodes) AND empty($nodes['errors']))
		{

			foreach ($nodes AS $node)
			{
				$channels[$node['nodeid']] = array(
					'nodeid' 		=> $node['nodeid'],
					'routeid' 		=> $node['routeid'],
					'title'			=> $node['title'],
					'description'		=> $node['description'],
					'parentid' 		=> $node['parentid'],
					'textcount'		=> $node['textcount'],
					'totalcount'		=> $node['totalcount'],
					'viewing'		=> 0, //@TODO: is the number of 'viewing' users implemented in api?
					'lastcontent' 	=> array(
						'nodeid'	=> $node['lastcontentid'],
						'title'		=> '',
						'authorname'	=> $node['lastcontentauthor'],
						'userid'	=> $node['lastauthorid'],
						'starter'	=> array(),
					),
					'subchannels'		=> array(),
				);
			}

			foreach ($channels as $channel)
			{
				$nodeId = $channel['nodeid'];
				$parentId = $channel['parentid'];
				if ($channel['lastcontent']['nodeid'] > 0)
				{
					$node = $api->callApi('node', 'getFullContentforNodes', array(array($channel['lastcontent']['nodeid'])));
					if (is_array($node))
					{
						$node = array_pop($node);
					}
					$channels[$nodeId]['lastcontent']['title'] = $node['content']['title'];
					$channels[$nodeId]['lastcontent']['created'] = $node['content']['created'];
					$channels[$nodeId]['lastcontent']['parentid'] = $node['content']['parentid'];
					$channels[$nodeId]['lastcontent']['starter']['nodeid'] = $node['content']['starter'];
					$channels[$nodeId]['lastcontent']['starter']['routeid'] = $node['content']['starterroute'];
					$channels[$nodeId]['lastcontent']['starter']['title'] = $node['content']['startertitle'];
				}

				if (isset($channels[$parentId]))
				{
					// assign by reference, so subchannels can be filled in later
					$channels[$parentId]['subchannels'][$nodeId] =& $channels[$nodeId];
				}
				else
				{
					// assign by reference, so subchannels can be filled in later
					$channelHierarchy[$nodeId] =& $channels[$nodeId];
				}
			}
			$templater->register('channels', $channelHierarchy);
		}
		else
		{
			$templater->register('channels', $nodes);
		}

		$results = $templater->render();
		echo $results;
	}

	protected function processActivityStream($nodes, $showChannelInfo, $view)
	{
		$result = array(
			'total' 	=> 0,
			'total_with_sticky' 	=> 0,
			'lastDate'	=> 0,
			'template'	=> '',
			'pageinfo'	=> array(
				'pagenumber'	=> 1,
				'totalpages'	=> 1
			),
		);
		if(!isset($nodes['errors']) AND !empty($nodes['results']))
		{
			foreach ($nodes['results'] AS $node)
			{
				$templateName = 'display_contenttype_conversationreply_' . $node['content']['contenttypeclass'];
				//only include the starter without replies yet or the latest reply or comment
				if (
					$view == 'channel'
					 OR
					(
						$node['content']['starter'] == $node['content']['nodeid']
						 AND
						isset($node['content']['startertotalcount'])
						 AND
						$node['content']['startertotalcount'] == 1
					)
					 OR
					(
						isset($node['content']['startertotalcount'])
						 AND
						 $node['content']['starterlastcontentid'] == $node['content']['nodeid']
					)
				)
				{
					$conversation = $node['content'];
				}
				else
				{
					// we are not interested in this record
					continue;
				}

				$templater = new vB5_Template($templateName);
				$templater->register('conversation', $conversation);
				$templater->register('reportActivity', true);
				$templater->register('showChannelInfo', $showChannelInfo);

				$result['template'] .= "\n" . $templater->render() . "\n";
				$result['total']++;
				$result['lastDate'] = max($result['lastDate'], $node['publishdate']);
			}
			$result['pageinfo']['pagenumber'] = $nodes['pagenumber'];
			$result['pageinfo']['totalpages'] = $nodes['totalpages'];
			$result['pageinfo']['resultId'] = $nodes['resultId'];
		}
		$result['total_with_sticky'] = $result['total'];
		return $result;
	}

	protected function processConversationDetail($nodes, $filters)
	{
		$view = $filters['view'];
		$result = array(
			'total' 	=> 0,
			'lastDate'	=> 0,
			'template'	=> '',
			'pageinfo'	=> array(
				'pagenumber'	=> 1,
				'totalpages'	=> 1,
			),
		);
		if(!isset($nodes['errors']) AND !empty($nodes['results']))
		{
			$showInlineMod = ($view == 'thread');
			if ($view == 'thread')
			{
				$showInlineMod =  true;
				$templateSuffix = 'starter';
				$pagingInfo = array(
					'currentpage'	=> $filters['pagenum'],
					'perpage'		=> $filters['per-page']
				);
			}
			else
			{
				$showInlineMod = false;
				$templateSuffix = 'reply';
				$pagingInfo = array();
			}
			$baseTemplateName = 'display_contenttype_' . ($view == 'stream' ? 'conversation%s_' : 'conversation%s_threadview_');
			$postIndex =  0;
			foreach ($nodes['results'] AS $node)
			{
				$updateIndex = true;
				$templateName = $baseTemplateName;
				if ($node['content']['starter'] == $node['content']['nodeid'])
				{
					$templateName = sprintf($templateName, $templateSuffix);
					$templateName .= $node['content']['contenttypeclass'];
					$conversation = $node['content'];
					$postIndex = 1;
					$updateIndex = false;
				}
				elseif ($view == 'thread' AND $node['content']['parentid'] != $node['content']['starter'])
				{
					//we don't need comments for thread view
					continue;
				}
				else
				{
					$templateName = sprintf($templateName, 'reply');
					$templateName .= $node['content']['contenttypeclass'];
					$conversation = $node['content'];
				}

				$templater = new vB5_Template($templateName);
				$templater->register('nodeid', $conversation['nodeid']);
				$templater->register('conversation', $conversation);
				$templater->register('reportActivity', false);
				$templater->register('showInlineMod', $showInlineMod);
				$templater->register('pagingInfo', $pagingInfo);
				if ($conversation['unpublishdate'])
				{
					$templater->register('hidePostIndex', true);
					$templater->register('postIndex', null);
				}
				else
				{
					$templater->register('postIndex', $postIndex);
					if ($updateIndex)
					{
						$postIndex++;
					}
				}

				$result['template'] .= "\n" . $templater->render() . "\n";
				$result['total']++;
				$result['lastDate'] = max($result['lastDate'], $node['publishdate']);
			}
			$result['pageinfo']['pagenumber'] = $nodes['pagenumber'];
			$result['pageinfo']['totalpages'] = $nodes['totalpages'];
			$result['pageinfo']['resultId'] = isset($nodes['resultId']) ? $nodes['resultId'] : null;
		}
		$result['total_with_sticky'] = $result['total'];
		return $result;
	}

	protected function processTopics($nodes, $stickynodes)
	{
		$result = array(
			'total' 			=> 0,
			'total_with_sticky'	=> 0,
			'lastDate'			=> 0,
			'template'			=> '',
			'pageinfo'	=> array(
				'pagenumber'	=> 1,
				'totalpages'	=> 1,
			),
		);

		$templater = new vB5_Template('display_Topics');
		$canmoderate  = false;
		if (!isset($nodes['errors']) AND !empty($nodes['results']))
		{
			foreach ($nodes['results'] AS $key => $node)
			{
				//only include the starter
				if ($node['content']['contenttypeclass'] == 'Channel' OR $node['content']['starter'] != $node['content']['nodeid'])
				{
					unset($nodes['results'][$key]);
				}
				else
				{
					$result['lastDate'] = max($result['lastDate'], $node['content']['publishdate']);
				}
				if (!empty($node['content']['permissions']['canmoderate']) AND !$canmoderate)
				{
					$canmoderate = 1;
					$templater->register('canmoderate', $canmoderate);
				}
			}

			$templater->register('topics', $nodes['results']);

			$result['total_with_sticky'] = $result['total'] = count($nodes['results']);
			$result['pageinfo']['pagenumber'] = $nodes['pagenumber'];
			$result['pageinfo']['totalpages'] = $nodes['totalpages'];
			$result['pageinfo']['resultId'] = $nodes['resultId'];
		}
		elseif (isset($nodes['errors']))
		{
			$templater->register('topics', $nodes);
		}

		if (!isset($stickynodes['errors']) AND !empty($stickynodes['results']))
		{
			$result['total_with_sticky'] = $result['total'] + count ($stickynodes['results']);
			$sticky_templater = new vB5_Template('display_Topics');
			$sticky_templater->register('topics', $stickynodes['results']);
			$sticky_templater->register('topic_list_class', 'sticky-list');
			$sticky_templater->register('canmoderate', $canmoderate);
			$result['template'] .= "\n" . $sticky_templater->render() . "\n";
			$templater->register('no_header', 1);
		}

		if (!empty($nodes['results']) OR empty($stickynodes['results']))
		{
			$result['template'] .= "\n" . $templater->render() . "\n";
		}
		return $result;
	}
}

/*======================================================================*\
|| ####################################################################
|| # 
|| # CVS: $RCSfile$ - $Revision: 40911 $
|| ####################################################################
\*======================================================================*/
