Completed
Pull Request — master (#434)
by Joas
05:49
created

GroupHelper::addActivity()   C

Complexity

Conditions 9
Paths 7

Size

Total Lines 62
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 47
CRAP Score 9

Importance

Changes 5
Bugs 1 Features 1
Metric Value
c 5
b 1
f 1
dl 0
loc 62
ccs 47
cts 47
cp 1
rs 6.6867
cc 9
eloc 40
nc 7
nop 1
crap 9

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * ownCloud - Activity App
5
 *
6
 * @author Joas Schilling
7
 * @copyright 2014 Joas Schilling [email protected]
8
 *
9
 * This library is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
11
 * License as published by the Free Software Foundation; either
12
 * version 3 of the License, or any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OCA\Activity;
25
26
use OCA\Activity\Parameter\Collection;
27
use OCA\Activity\Parameter\IParameter;
28
use OCP\Activity\IEvent;
29
use OCP\Activity\IManager;
30
use OCP\IL10N;
31
32
class GroupHelper {
33
	/** @var array */
34
	protected $activities = array();
35
36
	/** @var array */
37
	protected $openGroup = array();
38
39
	/** @var string */
40
	protected $groupKey = '';
41
42
	/** @var int */
43
	protected $groupTime = 0;
44
45
	/** @var bool */
46
	protected $allowGrouping;
47
48
	/** @var \OCP\Activity\IManager */
49
	protected $activityManager;
50
51
	/** @var \OCA\Activity\DataHelper */
52
	protected $dataHelper;
53
54
	/**
55
	 * @param \OCP\Activity\IManager $activityManager
56
	 * @param \OCA\Activity\DataHelper $dataHelper
57
	 * @param bool $allowGrouping
58
	 */
59 32
	public function __construct(IManager $activityManager, DataHelper $dataHelper, $allowGrouping) {
60 32
		$this->allowGrouping = $allowGrouping;
61
62 32
		$this->activityManager = $activityManager;
63 32
		$this->dataHelper = $dataHelper;
64 32
	}
65
66
	/**
67
	 * @param string $user
68
	 */
69 6
	public function setUser($user) {
70 6
		$this->dataHelper->setUser($user);
71 6
	}
72
73
	/**
74
	 * @param IL10N $l
75
	 */
76 1
	public function setL10n(IL10N $l) {
77 1
		$this->dataHelper->setL10n($l);
78 1
	}
79
80
	/**
81
	 * Add an activity to the internal array
82
	 *
83
	 * @param array $activity
84
	 */
85 12
	public function addActivity($activity) {
86 12
		$activity['activity_id'] = (int) $activity['activity_id'];
87 12
		$activity['timestamp'] = (int) $activity['timestamp'];
88 12
		$activity['object_id'] = (int) $activity['object_id'];
89 12
		$activity['object_name'] = (string) $activity['file'];
90 12
		unset($activity['priority']);
91 12
		unset($activity['file']);
92
93 12
		$event = $this->getEventFromArray(array_merge($activity, [
94 12
			'subjectparams' => [],
95 12
			'messageparams' => [],
96 12
		]));
97
98 12
		$activity['subjectparams_array'] = $this->dataHelper->getParameters($event, 'subject', $activity['subjectparams']);
99 12
		$activity['messageparams_array'] = $this->dataHelper->getParameters($event, 'message', $activity['messageparams']);
100
101 12
		$groupKey = $this->getGroupKey($activity);
102 12
		if ($groupKey === false) {
103 5
			$this->closeOpenGroup();
104 5
			$this->activities[] = $activity;
105 5
			return;
106
		}
107
108
		// Only group when the event has the same group key
109
		// and the time difference is not bigger than 3 days.
110 8
		if ($groupKey === $this->groupKey &&
111 4
			abs($activity['timestamp'] - $this->groupTime) < (3 * 24 * 60 * 60)
112 8
			&& (!isset($this->openGroup['activity_ids']) || sizeof($this->openGroup['activity_ids']) <= 5)
113 8
		) {
114 2
			$parameter = $this->getGroupParameter($activity);
115 2
			if ($parameter !== false) {
116
				/** @var IParameter $parameterInstance */
117 2
				$parameterInstance = $this->openGroup['subjectparams_array'][$parameter];
118
119 2
				if (!($parameterInstance instanceof Collection)) {
120 1
					$collection = $this->dataHelper->createCollection();
121 1
					$collection->addParameter($parameterInstance);
122 1
					$parameterInstance = $collection;
123 1
				}
124
125
				/** @var Collection $parameterInstance */
126 2
				$parameterInstance->addParameter($activity['subjectparams_array'][$parameter]);
127 2
				$this->openGroup['subjectparams_array'][$parameter] = $parameterInstance;
128
129 2
				if (!isset($this->openGroup['activity_ids'])) {
130 1
					$this->openGroup['activity_ids'] = [(int) $this->openGroup['activity_id']];
131 1
					$this->openGroup['files'] = [
132 1
						$this->openGroup['object_id'] => $this->openGroup['object_name']
133 1
					];
134 1
				}
135 2
				$this->openGroup['activity_ids'][] = (int) $activity['activity_id'];
136
137 2
				$this->openGroup['files'][$activity['object_id']] = $activity['object_name'];
138 2
			}
139 2
		} else {
140 6
			$this->closeOpenGroup();
141
142 6
			$this->groupKey = $groupKey;
143 6
			$this->groupTime = $activity['timestamp'];
144 6
			$this->openGroup = $activity;
145
		}
146 8
	}
147
148
	/**
149
	 * Closes the currently open group and adds it to the list of activities
150
	 */
151 13
	protected function closeOpenGroup() {
152 13
		if (!empty($this->openGroup)) {
153 7
			$this->activities[] = $this->openGroup;
154 7
		}
155
156 13
		$this->openGroup = [];
157 13
		$this->groupKey = '';
158 13
		$this->groupTime = 0;
159 13
	}
160
161
	/**
162
	 * Get grouping key for an activity
163
	 *
164
	 * @param array $activity
165
	 * @return false|string False, if grouping is not allowed, grouping key otherwise
166
	 */
167 7
	protected function getGroupKey($activity) {
168 7
		if ($this->getGroupParameter($activity) === false) {
169 4
			return false;
170
		}
171
172
		// FIXME
173
		// Non-local users are currently not distinguishable, so grouping them might
174
		// remove the information how many different users performed the same action.
175
		// So we do not group them anymore, until we found another solution.
176 4
		if ($activity['user'] === '') {
177 1
			return false;
178
		}
179
180 3
		return $activity['app'] . '|' . $activity['user'] . '|' . $activity['subject'] . '|' . $activity['object_type'];
181
	}
182
183
	/**
184
	 * Get the parameter which is the varying part
185
	 *
186
	 * @param array $activity
187
	 * @return bool|int False if the activity should not be grouped, parameter position otherwise
188
	 */
189 8
	protected function getGroupParameter($activity) {
190 8
		if (!$this->allowGrouping) {
191 2
			return false;
192
		}
193
194
		// Allow other apps to group their notifications
195 6
		return $this->activityManager->getGroupParameter($activity);
196
	}
197
198
	/**
199
	 * Get the prepared activities
200
	 *
201
	 * @return array translated activities ready for use
202
	 */
203 8
	public function getActivities() {
204 8
		$this->closeOpenGroup();
205
206 8
		$return = array();
207 8
		foreach ($this->activities as $activity) {
208 6
			$this->activityManager->setFormattingObject($activity['object_type'], $activity['object_id']);
209 6
			$activity = $this->dataHelper->formatStrings($activity, 'subject');
210 6
			$activity = $this->dataHelper->formatStrings($activity, 'message');
211
212 6
			foreach ($activity['subjectparams'] as $i => $param) {
0 ignored issues
show
Bug introduced by
The expression $activity['subjectparams'] of type string|array<string,stri..."full\":\"string\"}>"}> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
213
				/** @var IParameter $param */
214 4
				$activity['subjectparams'][$i] = $param->getParameterInfo();
215 6
			}
216 6
			foreach ($activity['messageparams'] as $i => $param) {
0 ignored issues
show
Bug introduced by
The expression $activity['messageparams'] of type string|array<string,stri..."full\":\"string\"}>"}> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
217
				/** @var IParameter $param */
218
				$activity['messageparams'][$i] = $param->getParameterInfo();
219 6
			}
220
221 6
			$activity['typeicon'] = $this->activityManager->getTypeIcon($activity['type']);
222 6
			$return[] = $activity;
223 8
		}
224 8
		$this->activityManager->setFormattingObject('', 0);
225 8
		$this->activities = [];
226
227 8
		return $return;
228
	}
229
230
	/**
231
	 * @param array $activity
232
	 * @return IEvent
233
	 */
234 6
	public function getEventFromArray(array $activity) {
235 6
		$event = $this->activityManager->generateEvent();
236 6
		$event->setApp($activity['app'])
237 6
			->setType($activity['type'])
238 6
			->setAffectedUser($activity['affecteduser'])
239 6
			->setAuthor($activity['user'])
240 6
			->setTimestamp($activity['timestamp'])
241 6
			->setSubject($activity['subject'], $activity['subjectparams'])
242 6
			->setMessage($activity['message'], $activity['messageparams'])
243 6
			->setObject($activity['object_type'], $activity['object_id'], $activity['object_name'])
244 6
			->setLink($activity['link']);
245
246 6
		return $event;
247
	}
248
}
249