Completed
Pull Request — master (#3297)
by Robin
14:21 queued 05:09
created

Helper   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 262
Duplicated Lines 13.74 %

Coupling/Cohesion

Components 2
Dependencies 13

Importance

Changes 0
Metric Value
dl 36
loc 262
rs 8.8
c 0
b 0
f 0
wmc 36
lcom 2
cbo 13

8 Methods

Rating   Name   Duplication   Size   Complexity  
C generateTarget() 0 27 7
C delete() 10 71 11
A getDefaultExpireSetting() 0 17 3
A calcExpireDate() 0 11 1
C calculateExpireDate() 0 24 7
A fixRemoteURL() 9 9 2
A splitUserRemote() 0 10 2
B isSameUserOnSameServer() 17 24 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Björn Schießle <[email protected]>
6
 * @author Joas Schilling <[email protected]>
7
 * @author Miguel Prokop <[email protected]>
8
 * @author Morris Jobke <[email protected]>
9
 * @author Robin Appelman <[email protected]>
10
 * @author Robin McCorkell <[email protected]>
11
 * @author Thomas Müller <[email protected]>
12
 * @author Vincent Petry <[email protected]>
13
 *
14
 * @license AGPL-3.0
15
 *
16
 * This code is free software: you can redistribute it and/or modify
17
 * it under the terms of the GNU Affero General Public License, version 3,
18
 * as published by the Free Software Foundation.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
 * GNU Affero General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU Affero General Public License, version 3,
26
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
27
 *
28
 */
29
30
namespace OC\Share;
31
32
use OC\HintException;
33
34
class Helper extends \OC\Share\Constants {
35
36
	/**
37
	 * Generate a unique target for the item
38
	 * @param string $itemType
39
	 * @param string $itemSource
40
	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
41
	 * @param string $shareWith User or group the item is being shared with
42
	 * @param string $uidOwner User that is the owner of shared item
43
	 * @param string $suggestedTarget The suggested target originating from a reshare (optional)
44
	 * @param int $groupParent The id of the parent group share (optional)
45
	 * @throws \Exception
46
	 * @return string Item target
47
	 */
48
	public static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $suggestedTarget = null, $groupParent = null) {
0 ignored issues
show
Unused Code introduced by
The parameter $uidOwner is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $groupParent is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
49
		// FIXME: $uidOwner and $groupParent seems to be unused
50
		$backend = \OC\Share\Share::getBackend($itemType);
51
		if ($shareType === self::SHARE_TYPE_LINK || $shareType === self::SHARE_TYPE_REMOTE) {
52
			if (isset($suggestedTarget)) {
53
				return $suggestedTarget;
54
			}
55
			return $backend->generateTarget($itemSource, false);
56
		} else {
57
			if ($shareType == self::SHARE_TYPE_USER) {
58
				// Share with is a user, so set share type to user and groups
59
				$shareType = self::$shareTypeUserAndGroups;
60
			}
61
62
			// Check if suggested target exists first
63
			if (!isset($suggestedTarget)) {
64
				$suggestedTarget = $itemSource;
65
			}
66
			if ($shareType == self::SHARE_TYPE_GROUP) {
67
				$target = $backend->generateTarget($suggestedTarget, false);
68
			} else {
69
				$target = $backend->generateTarget($suggestedTarget, $shareWith);
70
			}
71
72
			return $target;
73
		}
74
	}
75
76
	/**
77
	 * Delete all reshares and group share children of an item
78
	 * @param int $parent Id of item to delete
79
	 * @param bool $excludeParent If true, exclude the parent from the delete (optional)
80
	 * @param string $uidOwner The user that the parent was shared with (optional)
81
	 * @param int $newParent new parent for the childrens
82
	 * @param bool $excludeGroupChildren exclude group children elements
83
	 */
84
	public static function delete($parent, $excludeParent = false, $uidOwner = null, $newParent = null, $excludeGroupChildren = false) {
85
		$ids = array($parent);
86
		$deletedItems = array();
87
		$changeParent = array();
88
		$parents = array($parent);
89
		while (!empty($parents)) {
90
			$parents = "'".implode("','", $parents)."'";
91
			// Check the owner on the first search of reshares, useful for
92
			// finding and deleting the reshares by a single user of a group share
93
			$params = array();
94
			if (count($ids) == 1 && isset($uidOwner)) {
95
				// FIXME: don't concat $parents, use Docrine's PARAM_INT_ARRAY approach
96
				$queryString = 'SELECT `id`, `share_with`, `item_type`, `share_type`, ' .
97
					'`item_target`, `file_target`, `parent` ' .
98
					'FROM `*PREFIX*share` ' .
99
					'WHERE `parent` IN ('.$parents.') AND `uid_owner` = ? ';
100
				$params[] = $uidOwner;
101
			} else {
102
				$queryString = 'SELECT `id`, `share_with`, `item_type`, `share_type`, ' .
103
					'`item_target`, `file_target`, `parent`, `uid_owner` ' .
104
					'FROM `*PREFIX*share` WHERE `parent` IN ('.$parents.') ';
105
			}
106
			if ($excludeGroupChildren) {
107
				$queryString .= ' AND `share_type` != ?';
108
				$params[] = self::$shareTypeGroupUserUnique;
109
			}
110
			$query = \OC_DB::prepare($queryString);
111
			$result = $query->execute($params);
112
			// Reset parents array, only go through loop again if items are found
113
			$parents = array();
114
			while ($item = $result->fetchRow()) {
115
				$tmpItem = array(
116
					'id' => $item['id'],
117
					'shareWith' => $item['share_with'],
118
					'itemTarget' => $item['item_target'],
119
					'itemType' => $item['item_type'],
120
					'shareType' => (int)$item['share_type'],
121
				);
122
				if (isset($item['file_target'])) {
123
					$tmpItem['fileTarget'] = $item['file_target'];
124
				}
125
				// if we have a new parent for the child we remember the child
126
				// to update the parent, if not we add it to the list of items
127
				// which should be deleted
128
				if ($newParent !== null) {
129
					$changeParent[] = $item['id'];
130
				} else {
131
					$deletedItems[] = $tmpItem;
132
					$ids[] = $item['id'];
133
					$parents[] = $item['id'];
134
				}
135
			}
136
		}
137
		if ($excludeParent) {
138
			unset($ids[0]);
139
		}
140
141 View Code Duplication
		if (!empty($changeParent)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
142
			$idList = "'".implode("','", $changeParent)."'";
143
			$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `parent` = ? WHERE `id` IN ('.$idList.')');
144
			$query->execute(array($newParent));
145
		}
146
147 View Code Duplication
		if (!empty($ids)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
148
			$idList = "'".implode("','", $ids)."'";
149
			$query = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `id` IN ('.$idList.')');
150
			$query->execute();
151
		}
152
153
		return $deletedItems;
154
	}
155
156
	/**
157
	 * get default expire settings defined by the admin
158
	 * @return array contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays'
159
	 */
160
	public static function getDefaultExpireSetting() {
161
162
		$config = \OC::$server->getConfig();
163
164
		$defaultExpireSettings = array('defaultExpireDateSet' => false);
165
166
		// get default expire settings
167
		$defaultExpireDate = $config->getAppValue('core', 'shareapi_default_expire_date', 'no');
168
		if ($defaultExpireDate === 'yes') {
169
			$enforceExpireDate = $config->getAppValue('core', 'shareapi_enforce_expire_date', 'no');
170
			$defaultExpireSettings['defaultExpireDateSet'] = true;
171
			$defaultExpireSettings['expireAfterDays'] = (int)($config->getAppValue('core', 'shareapi_expire_after_n_days', '7'));
172
			$defaultExpireSettings['enforceExpireDate'] = $enforceExpireDate === 'yes' ? true : false;
173
		}
174
175
		return $defaultExpireSettings;
176
	}
177
178
	public static function calcExpireDate() {
179
		$expireAfter = \OC\Share\Share::getExpireInterval() * 24 * 60 * 60;
180
		$expireAt = time() + $expireAfter;
181
		$date = new \DateTime();
182
		$date->setTimestamp($expireAt);
183
		$date->setTime(0, 0, 0);
184
		//$dateString = $date->format('Y-m-d') . ' 00:00:00';
185
186
		return $date;
187
188
	}
189
190
	/**
191
	 * calculate expire date
192
	 * @param array $defaultExpireSettings contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays'
193
	 * @param int $creationTime timestamp when the share was created
194
	 * @param int $userExpireDate expire timestamp set by the user
195
	 * @return mixed integer timestamp or False
196
	 */
197
	public static function calculateExpireDate($defaultExpireSettings, $creationTime, $userExpireDate = null) {
198
199
		$expires = false;
200
		$defaultExpires = null;
201
202
		if (!empty($defaultExpireSettings['defaultExpireDateSet'])) {
203
			$defaultExpires = $creationTime + $defaultExpireSettings['expireAfterDays'] * 86400;
204
		}
205
206
207
		if (isset($userExpireDate)) {
208
			// if the admin decided to enforce the default expire date then we only take
209
			// the user defined expire date of it is before the default expire date
210
			if ($defaultExpires && !empty($defaultExpireSettings['enforceExpireDate'])) {
211
				$expires = min($userExpireDate, $defaultExpires);
212
			} else {
213
				$expires = $userExpireDate;
214
			}
215
		} else if ($defaultExpires && !empty($defaultExpireSettings['enforceExpireDate'])) {
216
			$expires = $defaultExpires;
217
		}
218
219
		return $expires;
220
	}
221
222
	/**
223
	 * Strips away a potential file names and trailing slashes:
224
	 * - http://localhost
225
	 * - http://localhost/
226
	 * - http://localhost/index.php
227
	 * - http://localhost/index.php/s/{shareToken}
228
	 *
229
	 * all return: http://localhost
230
	 *
231
	 * @param string $remote
232
	 * @return string
233
	 */
234 View Code Duplication
	protected static function fixRemoteURL($remote) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
235
		$remote = str_replace('\\', '/', $remote);
236
		if ($fileNamePosition = strpos($remote, '/index.php')) {
237
			$remote = substr($remote, 0, $fileNamePosition);
238
		}
239
		$remote = rtrim($remote, '/');
240
241
		return $remote;
242
	}
243
244
	/**
245
	 * split user and remote from federated cloud id
246
	 *
247
	 * @param string $id
248
	 * @return string[]
249
	 * @throws HintException
250
	 */
251
	public static function splitUserRemote($id) {
252
		try {
253
			$cloudId = \OC::$server->getCloudIdManager()->resolveCloudId($id);
254
			return [$cloudId->getUser(), $cloudId->getRemote()];
255
		} catch (\InvalidArgumentException $e) {
256
			$l = \OC::$server->getL10N('core');
257
			$hint = $l->t('Invalid Federated Cloud ID');
258
			throw new HintException('Invalid Federated Cloud ID', $hint, 0, $e);
259
		}
260
	}
261
262
	/**
263
	 * check if two federated cloud IDs refer to the same user
264
	 *
265
	 * @param string $user1
266
	 * @param string $server1
267
	 * @param string $user2
268
	 * @param string $server2
269
	 * @return bool true if both users and servers are the same
270
	 */
271
	public static function isSameUserOnSameServer($user1, $server1, $user2, $server2) {
272
		$normalizedServer1 = strtolower(\OC\Share\Share::removeProtocolFromUrl($server1));
273
		$normalizedServer2 = strtolower(\OC\Share\Share::removeProtocolFromUrl($server2));
274
275 View Code Duplication
		if (rtrim($normalizedServer1, '/') === rtrim($normalizedServer2, '/')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
276
			// FIXME this should be a method in the user management instead
277
			\OCP\Util::emitHook(
278
					'\OCA\Files_Sharing\API\Server2Server',
279
					'preLoginNameUsedAsUserName',
280
					array('uid' => &$user1)
281
			);
282
			\OCP\Util::emitHook(
283
					'\OCA\Files_Sharing\API\Server2Server',
284
					'preLoginNameUsedAsUserName',
285
					array('uid' => &$user2)
286
			);
287
288
			if ($user1 === $user2) {
289
				return true;
290
			}
291
		}
292
293
		return false;
294
	}
295
}
296