Completed
Push — master ( 6ca8ce...06e969 )
by Lukas
47:33 queued 38:57
created

Calendar::getResourceId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Joas Schilling <[email protected]>
6
 * @author Lukas Reschke <[email protected]>
7
 * @author Thomas Müller <[email protected]>
8
 *
9
 * @license AGPL-3.0
10
 *
11
 * This code is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License, version 3,
13
 * as published by the Free Software Foundation.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License, version 3,
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
22
 *
23
 */
24
namespace OCA\DAV\CalDAV;
25
26
use OCA\DAV\DAV\Sharing\IShareable;
27
use OCP\IL10N;
28
use Sabre\CalDAV\Backend\BackendInterface;
29
use Sabre\DAV\Exception\Forbidden;
30
use Sabre\DAV\Exception\NotFound;
31
use Sabre\DAV\PropPatch;
32
33
class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
34
35
	public function __construct(BackendInterface $caldavBackend, $calendarInfo, IL10N $l10n) {
36
		parent::__construct($caldavBackend, $calendarInfo);
37
38
		if ($this->getName() === BirthdayService::BIRTHDAY_CALENDAR_URI) {
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
39
			$this->calendarInfo['{DAV:}displayname'] = $l10n->t('Contact birthdays');
40
		}
41
	}
42
43
	/**
44
	 * Updates the list of shares.
45
	 *
46
	 * The first array is a list of people that are to be added to the
47
	 * resource.
48
	 *
49
	 * Every element in the add array has the following properties:
50
	 *   * href - A url. Usually a mailto: address
51
	 *   * commonName - Usually a first and last name, or false
52
	 *   * summary - A description of the share, can also be false
53
	 *   * readOnly - A boolean value
54
	 *
55
	 * Every element in the remove array is just the address string.
56
	 *
57
	 * @param array $add
58
	 * @param array $remove
59
	 * @return void
60
	 */
61
	function updateShares(array $add, array $remove) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
62
		/** @var CalDavBackend $calDavBackend */
63
		$calDavBackend = $this->caldavBackend;
64
		$calDavBackend->updateShares($this, $add, $remove);
65
	}
66
67
	/**
68
	 * Returns the list of people whom this resource is shared with.
69
	 *
70
	 * Every element in this array should have the following properties:
71
	 *   * href - Often a mailto: address
72
	 *   * commonName - Optional, for example a first + last name
73
	 *   * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
74
	 *   * readOnly - boolean
75
	 *   * summary - Optional, a description for the share
76
	 *
77
	 * @return array
78
	 */
79
	function getShares() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
80
		/** @var CalDavBackend $calDavBackend */
81
		$calDavBackend = $this->caldavBackend;
82
		return $calDavBackend->getShares($this->getResourceId());
83
	}
84
85
	/**
86
	 * @return int
87
	 */
88
	public function getResourceId() {
89
		return $this->calendarInfo['id'];
90
	}
91
92
	/**
93
	 * @return string
94
	 */
95
	public function getPrincipalURI() {
96
		return $this->calendarInfo['principaluri'];
97
	}
98
99 View Code Duplication
	function getACL() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
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...
100
		$acl =  [
101
			[
102
				'privilege' => '{DAV:}read',
103
				'principal' => $this->getOwner(),
104
				'protected' => true,
105
			]];
106
		if ($this->getName() !== BirthdayService::BIRTHDAY_CALENDAR_URI) {
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
107
			$acl[] = [
108
				'privilege' => '{DAV:}write',
109
				'principal' => $this->getOwner(),
110
				'protected' => true,
111
			];
112
		}
113
		if ($this->getOwner() !== parent::getOwner()) {
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getOwner() instead of getACL()). Are you sure this is correct? If so, you might want to change this to $this->getOwner().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
114
			$acl[] =  [
115
					'privilege' => '{DAV:}read',
116
					'principal' => parent::getOwner(),
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getOwner() instead of getACL()). Are you sure this is correct? If so, you might want to change this to $this->getOwner().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
117
					'protected' => true,
118
				];
119
			if ($this->canWrite()) {
120
				$acl[] = [
121
					'privilege' => '{DAV:}write',
122
					'principal' => parent::getOwner(),
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getOwner() instead of getACL()). Are you sure this is correct? If so, you might want to change this to $this->getOwner().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
123
					'protected' => true,
124
				];
125
			}
126
		}
127
		if ($this->isPublic()) {
128
			$acl[] = [
129
				'privilege' => '{DAV:}read',
130
				'principal' => 'principals/system/public',
131
				'protected' => true,
132
			];
133
		}
134
135
		/** @var CalDavBackend $calDavBackend */
136
		$calDavBackend = $this->caldavBackend;
137
		return $calDavBackend->applyShareAcl($this->getResourceId(), $acl);
138
	}
139
140
	function getChildACL() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
141
		return $this->getACL();
142
	}
143
144
	function getOwner() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
145
		if (isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal'])) {
146
			return $this->calendarInfo['{http://owncloud.org/ns}owner-principal'];
147
		}
148
		return parent::getOwner();
149
	}
150
151 View Code Duplication
	function delete() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
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...
152
		if (isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal'])) {
153
			$principal = 'principal:' . parent::getOwner();
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getOwner() instead of delete()). Are you sure this is correct? If so, you might want to change this to $this->getOwner().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
154
			$shares = $this->getShares();
155
			$shares = array_filter($shares, function($share) use ($principal){
156
				return $share['href'] === $principal;
157
			});
158
			if (empty($shares)) {
159
				throw new Forbidden();
160
			}
161
162
			/** @var CalDavBackend $calDavBackend */
163
			$calDavBackend = $this->caldavBackend;
164
			$calDavBackend->updateShares($this, [], [
165
				'href' => $principal
166
			]);
167
			return;
168
		}
169
		parent::delete();
170
	}
171
172
	function propPatch(PropPatch $propPatch) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
173
		$mutations = $propPatch->getMutations();
174
		// If this is a shared calendar, the user can only change the enabled property, to hide it.
175
		if (isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal']) && (sizeof($mutations) !== 1 || !isset($mutations['{http://owncloud.org/ns}calendar-enabled']))) {
176
			throw new Forbidden();
177
		}
178
		parent::propPatch($propPatch);
179
	}
180
181
	function getChild($name) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
182
183
		$obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $name);
184
185
		if (!$obj) {
186
			throw new NotFound('Calendar object not found');
187
		}
188
189
		if ($this->isShared() && $obj['classification'] === CalDavBackend::CLASSIFICATION_PRIVATE) {
190
			throw new NotFound('Calendar object not found');
191
		}
192
193
		$obj['acl'] = $this->getChildACL();
194
195
		return new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj);
196
197
	}
198
199 View Code Duplication
	function getChildren() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
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...
200
201
		$objs = $this->caldavBackend->getCalendarObjects($this->calendarInfo['id']);
202
		$children = [];
203
		foreach ($objs as $obj) {
204
			if ($this->isShared() && $obj['classification'] === CalDavBackend::CLASSIFICATION_PRIVATE) {
205
				continue;
206
			}
207
			$obj['acl'] = $this->getChildACL();
208
			$children[] = new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj);
209
		}
210
		return $children;
211
212
	}
213
214 View Code Duplication
	function getMultipleChildren(array $paths) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
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...
215
216
		$objs = $this->caldavBackend->getMultipleCalendarObjects($this->calendarInfo['id'], $paths);
217
		$children = [];
218
		foreach ($objs as $obj) {
219
			if ($this->isShared() && $obj['classification'] === CalDavBackend::CLASSIFICATION_PRIVATE) {
220
				continue;
221
			}
222
			$obj['acl'] = $this->getChildACL();
223
			$children[] = new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj);
224
		}
225
		return $children;
226
227
	}
228
229
	function childExists($name) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
230
		$obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $name);
231
		if (!$obj) {
232
			return false;
233
		}
234
		if ($this->isShared() && $obj['classification'] === CalDavBackend::CLASSIFICATION_PRIVATE) {
235
			return false;
236
		}
237
238
		return true;
239
	}
240
241
	function calendarQuery(array $filters) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
242
243
		$uris = $this->caldavBackend->calendarQuery($this->calendarInfo['id'], $filters);
244
		if ($this->isShared()) {
245
			return array_filter($uris, function ($uri) {
246
				return $this->childExists($uri);
247
			});
248
		}
249
250
		return $uris;
251
	}
252
253
	/**
254
	 * @param boolean $value
255
	 * @return string|null
256
	 */
257
	function setPublishStatus($value) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
258
		$publicUri = $this->caldavBackend->setPublishStatus($value, $this);
259
		$this->calendarInfo['publicuri'] = $publicUri;
260
		return $publicUri;
261
	}
262
263
	/**
264
	 * @return mixed $value
265
	 */
266
	function getPublishStatus() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
267
		return $this->caldavBackend->getPublishStatus($this);
268
	}
269
270
	private function canWrite() {
271
		if (isset($this->calendarInfo['{http://owncloud.org/ns}read-only'])) {
272
			return !$this->calendarInfo['{http://owncloud.org/ns}read-only'];
273
		}
274
		return true;
275
	}
276
277
	private function isPublic() {
278
		return isset($this->calendarInfo['{http://owncloud.org/ns}public']);
279
	}
280
281
	private function isShared() {
282
		return isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal']);
283
	}
284
285
	public function isSubscription() {
286
		return isset($this->calendarInfo['{http://calendarserver.org/ns/}source']);
287
	}
288
289
}
290