Completed
Push — master ( 424d62...2a7733 )
by Morris
11:53
created

CalendarSearchReport   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 132
Duplicated Lines 6.82 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 9
loc 132
rs 10
c 0
b 0
f 0
wmc 26
lcom 1
cbo 0

1 Method

Rating   Name   Duplication   Size   Complexity  
F xmlDeserialize() 9 84 26

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
 * @author Georg Ehrke <[email protected]>
4
 *
5
 * @copyright Copyright (c) 2017 Georg Ehrke <[email protected]>
6
 * @license GNU AGPL version 3 or any later version
7
 *
8
 * This code is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License, version 3,
10
 * as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License, version 3,
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
19
 *
20
 */
21
namespace OCA\DAV\CalDAV\Search\Xml\Request;
22
23
use Sabre\DAV\Exception\BadRequest;
24
use Sabre\Xml\Reader;
25
use Sabre\Xml\XmlDeserializable;
26
use OCA\DAV\CalDAV\Search\SearchPlugin;
27
28
/**
29
 * CalendarSearchReport request parser.
30
 *
31
 * This class parses the {urn:ietf:params:xml:ns:caldav}calendar-query
32
 * REPORT, as defined in:
33
 *
34
 * https:// link to standard
35
 */
36
class CalendarSearchReport implements XmlDeserializable {
37
38
	/**
39
	 * An array with requested properties.
40
	 *
41
	 * @var array
42
	 */
43
	public $properties;
44
45
	/**
46
	 * List of property/component filters.
47
	 *
48
	 * @var array
49
	 */
50
	public $filters;
51
52
	/**
53
	 * @var int
54
	 */
55
	public $limit;
56
57
	/**
58
	 * @var int
59
	 */
60
	public $offset;
61
62
	/**
63
	 * The deserialize method is called during xml parsing.
64
	 *
65
	 * This method is called statically, this is because in theory this method
66
	 * may be used as a type of constructor, or factory method.
67
	 *
68
	 * Often you want to return an instance of the current class, but you are
69
	 * free to return other data as well.
70
	 *
71
	 * You are responsible for advancing the reader to the next element. Not
72
	 * doing anything will result in a never-ending loop.
73
	 *
74
	 * If you just want to skip parsing for this element altogether, you can
75
	 * just call $reader->next();
76
	 *
77
	 * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
78
	 * the next element.
79
	 *
80
	 * @param Reader $reader
81
	 * @return mixed
82
	 */
83
	static function xmlDeserialize(Reader $reader) {
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...
84
		$elems = $reader->parseInnerTree([
85
			'{http://nextcloud.com/ns}comp-filter'  => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\CompFilter',
86
			'{http://nextcloud.com/ns}prop-filter'  => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter',
87
			'{http://nextcloud.com/ns}param-filter' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\ParamFilter',
88
			'{http://nextcloud.com/ns}search-term'  => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter',
89
			'{http://nextcloud.com/ns}limit'        => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\LimitFilter',
90
			'{http://nextcloud.com/ns}offset'       => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\OffsetFilter',
91
			'{DAV:}prop'                            => 'Sabre\\Xml\\Element\\KeyValue',
92
		]);
93
94
		$newProps = [
95
			'filters'    => [],
96
			'properties' => [],
97
			'limit'      => null,
98
			'offset'     => null
99
		];
100
101
		if (!is_array($elems)) {
102
			$elems = [];
103
		}
104
105
		foreach ($elems as $elem) {
106
			switch ($elem['name']) {
107
				case '{DAV:}prop':
108
					$newProps['properties'] = array_keys($elem['value']);
109
					break;
110
				case '{' . SearchPlugin::NS_Nextcloud . '}filter':
111
					foreach ($elem['value'] as $subElem) {
112
						if ($subElem['name'] === '{' . SearchPlugin::NS_Nextcloud . '}comp-filter') {
113 View Code Duplication
							if (!isset($newProps['filters']['comps']) || !is_array($newProps['filters']['comps'])) {
114
								$newProps['filters']['comps'] = [];
115
							}
116
							$newProps['filters']['comps'][] = $subElem['value'];
117
						} elseif ($subElem['name'] === '{' . SearchPlugin::NS_Nextcloud . '}prop-filter') {
118 View Code Duplication
							if (!isset($newProps['filters']['props']) || !is_array($newProps['filters']['props'])) {
119
								$newProps['filters']['props'] = [];
120
							}
121
							$newProps['filters']['props'][] = $subElem['value'];
122
						} elseif ($subElem['name'] === '{' . SearchPlugin::NS_Nextcloud . '}param-filter') {
123 View Code Duplication
							if (!isset($newProps['filters']['params']) || !is_array($newProps['filters']['params'])) {
124
								$newProps['filters']['params'] = [];
125
							}
126
							$newProps['filters']['params'][] = $subElem['value'];
127
						} elseif ($subElem['name'] === '{' . SearchPlugin::NS_Nextcloud . '}search-term') {
128
							$newProps['filters']['search-term'] = $subElem['value'];
129
						}
130
					}
131
					break;
132
				case '{' . SearchPlugin::NS_Nextcloud . '}limit':
133
					$newProps['limit'] = $elem['value'];
134
					break;
135
				case '{' . SearchPlugin::NS_Nextcloud . '}offset':
136
					$newProps['offset'] = $elem['value'];
137
					break;
138
139
			}
140
		}
141
142
		if (empty($newProps['filters'])) {
143
			throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}filter element is required for this request');
144
		}
145
146
		$propsOrParamsDefined = (!empty($newProps['filters']['props']) || !empty($newProps['filters']['params']));
147
		$noCompsDefined = empty($newProps['filters']['comps']);
148
		if ($propsOrParamsDefined && $noCompsDefined) {
149
			throw new BadRequest('{' . SearchPlugin::NS_Nextcloud . '}prop-filter or {' . SearchPlugin::NS_Nextcloud . '}param-filter given without any {' . SearchPlugin::NS_Nextcloud . '}comp-filter');
150
		}
151
152
		if (!isset($newProps['filters']['search-term'])) {
153
			throw new BadRequest('{' . SearchPlugin::NS_Nextcloud . '}search-term is required for this request');
154
		}
155
156
		if (empty($newProps['filters']['props']) && empty($newProps['filters']['params'])) {
157
			throw new BadRequest('At least one{' . SearchPlugin::NS_Nextcloud . '}prop-filter or {' . SearchPlugin::NS_Nextcloud . '}param-filter is required for this request');
158
		}
159
160
161
		$obj = new self();
162
		foreach ($newProps as $key => $value) {
163
			$obj->$key = $value;
164
		}
165
		return $obj;
166
	}
167
}
168