Passed
Push — master ( fce6df...8e01ff )
by Georg
14:04 queued 11s
created

UserLiveStatusListener   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 43
c 1
b 0
f 0
dl 0
loc 89
rs 10
wmc 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B handle() 0 47 9
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * @copyright Copyright (c) 2020, Georg Ehrke
7
 *
8
 * @author Georg Ehrke <[email protected]>
9
 *
10
 * @license AGPL-3.0
11
 *
12
 * This code is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License, version 3,
14
 * as published by the Free Software Foundation.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License, version 3,
22
 * along with this program. If not, see <http://www.gnu.org/licenses/>
23
 *
24
 */
25
26
namespace OCA\UserStatus\Listener;
27
28
use OCA\UserStatus\Db\UserStatus;
29
use OCA\UserStatus\Db\UserStatusMapper;
30
use OCP\AppFramework\Db\DoesNotExistException;
31
use OCP\AppFramework\Utility\ITimeFactory;
32
use OCP\EventDispatcher\IEventListener;
33
use OCP\EventDispatcher\Event;
34
use OCP\User\Events\UserLiveStatusEvent;
35
36
/**
37
 * Class UserDeletedListener
38
 *
39
 * @package OCA\UserStatus\Listener
40
 */
41
class UserLiveStatusListener implements IEventListener {
42
43
	/** @var UserStatusMapper */
44
	private $mapper;
45
46
	/** @var ITimeFactory */
47
	private $timeFactory;
48
49
	/** @var string[] */
50
	private $priorityOrderedStatuses = [
51
		'online',
52
		'away',
53
		'dnd',
54
		'invisible',
55
		'offline'
56
	];
57
58
	/** @var string[] */
59
	private $persistentUserStatuses = [
60
		'away',
61
		'dnd',
62
		'invisible',
63
	];
64
65
	/** @var int */
66
	private $offlineThreshold = 300;
67
68
	/**
69
	 * UserLiveStatusListener constructor.
70
	 *
71
	 * @param UserStatusMapper $mapper
72
	 * @param ITimeFactory $timeFactory
73
	 */
74
	public function __construct(UserStatusMapper $mapper,
75
								ITimeFactory $timeFactory) {
76
		$this->mapper = $mapper;
77
		$this->timeFactory = $timeFactory;
78
	}
79
80
	/**
81
	 * @inheritDoc
82
	 */
83
	public function handle(Event $event): void {
84
		if (!($event instanceof UserLiveStatusEvent)) {
85
			// Unrelated
86
			return;
87
		}
88
89
		$user = $event->getUser();
90
		try {
91
			$userStatus = $this->mapper->findByUserId($user->getUID());
92
		} catch (DoesNotExistException $ex) {
93
			$userStatus = new UserStatus();
94
			$userStatus->setUserId($user->getUID());
95
			$userStatus->setStatus('offline');
96
			$userStatus->setStatusTimestamp(0);
97
			$userStatus->setIsUserDefined(false);
98
		}
99
100
		// If the status is user-defined and one of the persistent statuses, we
101
		// will not override it.
102
		if ($userStatus->getIsUserDefined() &&
103
			\in_array($userStatus->getStatus(), $this->persistentUserStatuses, true)) {
104
			return;
105
		}
106
107
		$needsUpdate = false;
108
109
		// If the current status is older than 5 minutes,
110
		// treat it as outdated and update
111
		if ($userStatus->getStatusTimestamp() < ($this->timeFactory->getTime() - $this->offlineThreshold)) {
112
			$needsUpdate = true;
113
		}
114
115
		// If the emitted status is more important than the current status
116
		// treat it as outdated and update
117
		if (array_search($event->getStatus(), $this->priorityOrderedStatuses) < array_search($userStatus->getStatus(), $this->priorityOrderedStatuses)) {
118
			$needsUpdate = true;
119
		}
120
121
		if ($needsUpdate) {
122
			$userStatus->setStatus($event->getStatus());
123
			$userStatus->setStatusTimestamp($event->getTimestamp());
124
			$userStatus->setIsUserDefined(false);
125
126
			if ($userStatus->getId() === null) {
0 ignored issues
show
introduced by
The condition $userStatus->getId() === null is always false.
Loading history...
127
				$this->mapper->insert($userStatus);
128
			} else {
129
				$this->mapper->update($userStatus);
130
			}
131
		}
132
	}
133
}
134