Completed
Push — master ( 4ceab2...5384e5 )
by Sam
03:45
created

StatisticsManager::filterBySubscriptionStopped()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 11
ccs 0
cts 10
cp 0
rs 9.4285
cc 2
eloc 5
nc 2
nop 2
crap 6
1
<?php
2
3
namespace Jalle19\StatusManager\Manager;
4
5
use Jalle19\StatusManager\Database\InstanceQuery;
6
use Jalle19\StatusManager\Database\SubscriptionQuery;
7
use Jalle19\StatusManager\Database\User;
8
use Jalle19\StatusManager\Database\UserQuery;
9
use Jalle19\StatusManager\Message\AbstractMessage;
10
use Jalle19\StatusManager\Message\Handler\HandlerInterface;
11
use Jalle19\StatusManager\Message\Request\InstancesRequest;
12
use Jalle19\StatusManager\Message\Request\MostActiveWatchersRequest;
13
use Jalle19\StatusManager\Message\Request\PopularChannelsRequest;
14
use Jalle19\StatusManager\Message\Request\UsersRequest;
15
use Jalle19\StatusManager\Message\Response\InstancesResponse;
16
use Jalle19\StatusManager\Message\Response\MostActiveWatchersResponse;
17
use Jalle19\StatusManager\Message\Response\PopularChannelsResponse;
18
use Jalle19\StatusManager\Message\Response\UsersResponse;
19
use Jalle19\StatusManager\TimeFrame;
20
use Jalle19\tvheadend\exception\RequestFailedException;
21
use Propel\Runtime\ActiveQuery\Criteria;
22
use Propel\Runtime\Exception\PropelException;
23
use Ratchet\ConnectionInterface;
24
25
/**
26
 * Class StatisticsManager
27
 * @package   Jalle19\StatusManager\Manager
28
 * @copyright Copyright &copy; Sam Stenvall 2016-
29
 * @license   https://www.gnu.org/licenses/gpl.html The GNU General Public License v2.0
30
 */
31
class StatisticsManager extends AbstractManager implements HandlerInterface
32
{
33
34
	/**
35
	 * @inheritdoc
36
	 */
37
	public function handleMessage(AbstractMessage $message, ConnectionInterface $sender)
38
	{
39
		// Wrap database exceptions in the more generic RequestFailedException
40
		try
41
		{
42
			switch ($message->getType())
43
			{
44
				case AbstractMessage::TYPE_POPULAR_CHANNELS_REQUEST:
45
					/* @var PopularChannelsRequest $message */
46
					return new PopularChannelsResponse($message, $this->getPopularChannels(
47
						$message->getInstanceName(),
48
						$message->getUserName(),
49
						$message->getLimit(),
50
						$message->getTimeFrame()));
51
				case AbstractMessage::TYPE_MOST_ACTIVE_WATCHERS_REQUEST:
52
					/* @var MostActiveWatchersRequest $message */
53
					return new MostActiveWatchersResponse($message, $this->getMostActiveWatchers(
54
						$message->getInstanceName(),
55
						$message->getLimit(),
56
						$message->getTimeFrame()));
57
				case AbstractMessage::TYPE_INSTANCES_REQUEST:
58
					/* @var InstancesRequest $message */
59
					return new InstancesResponse($this->configuration->getInstances());
60
				case AbstractMessage::TYPE_USERS_REQUEST:
61
					/* @var UsersRequest $message */
62
					return new UsersResponse($this->getUsers($message->getInstanceName()));
63
			}
64
		}
65
		catch (PropelException $e)
66
		{
67
			throw new RequestFailedException('A database error occured: ' . $e->getMessage());
68
		}
69
70
		return false;
71
	}
72
73
74
	/**
75
	 * @param string      $instanceName
76
	 * @param string|null $userName
77
	 * @param int|null    $limit
78
	 * @param TimeFrame   $timeFrame
79
	 *
80
	 * @return array the popular channels
81
	 */
82
	private function getPopularChannels($instanceName, $userName, $limit, $timeFrame)
83
	{
84
		// Find the instance and the user
85
		$instance = InstanceQuery::create()->findOneByName($instanceName);
86
		$user     = UserQuery::create()->findOneByName($userName);
87
		$query    = SubscriptionQuery::create()->getPopularChannelsQuery($instance, $user);
88
89
		$query = $query->filterByLimit($limit);
90
		$query = $query->filterByTimeFrame($timeFrame);
91
		$query = $this->filterIgnoredUsers($instanceName, $query->useUserQuery())->endUse();
92
93
		return $query->find()->getData();
94
	}
95
96
97
	/**
98
	 * @param string    $instanceName
99
	 * @param int       $limit
100
	 * @param TimeFrame $timeFrame
101
	 *
102
	 * @return array
103
	 */
104
	private function getMostActiveWatchers($instanceName, $limit, $timeFrame)
105
	{
106
		$instance = InstanceQuery::create()->findOneByName($instanceName);
107
		$query    = UserQuery::create()->getMostActiveWatchersQuery($instance);
108
109
		$query = $query->filterByLimit($limit);
110
		$query = $query->useSubscriptionQuery()->filterByTimeFrame($timeFrame)->endUse();
111
		$query = $this->filterIgnoredUsers($instanceName, $query);
112
113
		return $query->find()->getData();
114
	}
115
116
117
	/**
118
	 * Returns all users found so far for the specified instance name
119
	 *
120
	 * @param string $instanceName
121
	 *
122
	 * @return User[]
123
	 */
124
	private function getUsers($instanceName)
125
	{
126
		$query = UserQuery::create();
127
		$query = $this->filterIgnoredUsers($instanceName, $query);
128
129
		return $query->findByInstanceName($instanceName)->getArrayCopy();
130
	}
131
132
133
	/**
134
	 * @param string    $instanceName
135
	 * @param UserQuery $query
136
	 *
137
	 * @return UserQuery
138
	 */
139
	private function filterIgnoredUsers($instanceName, UserQuery $query)
140
	{
141
		$instance     = $this->configuration->getInstanceByName($instanceName);
142
		$ignoredUsers = $instance->getIgnoredUsers();
143
144
		// Always ignore system users
145
		$ignoredUsers[] = User::NAME_DVR;
146
147
		foreach ($ignoredUsers as $ignoredUser)
148
			$query = $query->filterByName($ignoredUser, Criteria::NOT_EQUAL);
149
150
		return $query;
151
	}
152
153
}
154