Passed
Push — master ( 222d9e...5d29a9 )
by Christoph
23:13 queued 05:51
created

CalendarObject::delete()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 10
c 1
b 0
f 0
nc 6
nop 0
dl 0
loc 14
rs 9.2222
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * @copyright 2023 Ferdinand Thiessen <[email protected]>
6
 *
7
 * @author Ferdinand Thiessen <[email protected]>
8
 *
9
 * @license AGPL-3.0-or-later
10
 *
11
 * This program is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License as
13
 * published by the Free Software Foundation, either version 3 of the
14
 * License, or (at your option) any later version.
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
22
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23
 *
24
 */
25
26
namespace OCA\DAV\CalDAV\AppCalendar;
27
28
use OCP\Calendar\ICalendar;
29
use OCP\Calendar\ICreateFromString;
30
use OCP\Constants;
31
use Sabre\CalDAV\ICalendarObject;
32
use Sabre\DAV\Exception\Forbidden;
33
use Sabre\DAV\Exception\NotFound;
34
use Sabre\DAVACL\IACL;
35
use Sabre\VObject\Component\VCalendar;
36
use Sabre\VObject\Property\ICalendar\DateTime;
37
38
class CalendarObject implements ICalendarObject, IACL {
39
	private VCalendar $vobject;
40
	private AppCalendar $calendar;
41
	private ICalendar|ICreateFromString $backend;
42
43
	public function __construct(AppCalendar $calendar, ICalendar $backend, VCalendar $vobject) {
44
		$this->backend = $backend;
45
		$this->calendar = $calendar;
46
		$this->vobject = $vobject;
47
	}
48
49
	public function getOwner() {
50
		return $this->calendar->getOwner();
51
	}
52
53
	public function getGroup() {
54
		return $this->calendar->getGroup();
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->calendar->getGroup() targeting OCA\DAV\CalDAV\AppCalendar\AppCalendar::getGroup() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
55
	}
56
57
	public function getACL(): array {
58
		$acl = [
59
			[
60
				'privilege' => '{DAV:}read',
61
				'principal' => $this->getOwner(),
62
				'protected' => true,
63
			]
64
		];
65
		if ($this->calendar->getPermissions() & Constants::PERMISSION_UPDATE) {
66
			$acl[] = [
67
				'privilege' => '{DAV:}write-content',
68
				'principal' => $this->getOwner(),
69
				'protected' => true,
70
			];
71
		}
72
		return $acl;
73
	}
74
75
	public function setACL(array $acl): void {
76
		throw new Forbidden('Setting ACL is not supported on this node');
77
	}
78
79
	public function getSupportedPrivilegeSet(): ?array {
80
		return null;
81
	}
82
83
	public function put($data): void {
84
		if ($this->backend instanceof ICreateFromString && $this->calendar->getPermissions() & Constants::PERMISSION_UPDATE) {
85
			if (is_resource($data)) {
86
				$data = stream_get_contents($data) ?: '';
87
			}
88
			$this->backend->createFromString($this->getName(), $data);
89
		} else {
90
			throw new Forbidden('This calendar-object is read-only');
91
		}
92
	}
93
94
	public function get(): string {
95
		return $this->vobject->serialize();
96
	}
97
98
	public function getContentType(): string {
99
		return 'text/calendar; charset=utf-8';
100
	}
101
102
	public function getETag(): ?string {
103
		return null;
104
	}
105
106
	public function getSize() {
107
		return mb_strlen($this->vobject->serialize());
108
	}
109
110
	public function delete(): void {
111
		if ($this->backend instanceof ICreateFromString && $this->calendar->getPermissions() & Constants::PERMISSION_DELETE) {
112
			/** @var \Sabre\VObject\Component[] */
113
			$components = $this->vobject->getBaseComponents();
114
			foreach ($components as $key => $component) {
115
				$components[$key]->STATUS = 'CANCELLED';
116
				$components[$key]->SEQUENCE = isset($component->SEQUENCE) ? ((int)$component->SEQUENCE->getValue()) + 1 : 1;
0 ignored issues
show
Bug introduced by
The method getValue() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

116
				$components[$key]->SEQUENCE = isset($component->SEQUENCE) ? ((int)$component->SEQUENCE->/** @scrutinizer ignore-call */ getValue()) + 1 : 1;

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
117
				if ($component->name === 'VEVENT') {
118
					$components[$key]->METHOD = 'CANCEL';
119
				}
120
			}
121
			$this->backend->createFromString($this->getName(), (new VCalendar($components))->serialize());
122
		} else {
123
			throw new Forbidden('This calendar-object is read-only');
124
		}
125
	}
126
127
	public function getName(): string {
128
		// Every object is required to have an UID
129
		$base = $this->vobject->getBaseComponent();
130
		// This should never happen except the app provides invalid calendars (VEvent, VTodo... all require UID to be present)
131
		if ($base === null) {
132
			throw new NotFound('Invalid node');
133
		}
134
		if (isset($base->{'X-FILENAME'})) {
135
			return (string)$base->{'X-FILENAME'};
136
		}
137
		return (string)$base->UID . '.ics';
138
	}
139
140
	public function setName($name): void {
141
		throw new Forbidden('This calendar-object is read-only');
142
	}
143
144
	public function getLastModified(): ?int {
145
		$base = $this->vobject->getBaseComponent();
146
		if ($base !== null && $this->vobject->getBaseComponent()->{'LAST-MODIFIED'}) {
147
			/** @var DateTime */
148
			$lastModified = $this->vobject->getBaseComponent()->{'LAST-MODIFIED'};
149
			return $lastModified->getDateTime()->getTimestamp();
150
		}
151
		return null;
152
	}
153
}
154