MoveItems::Handle()   F
last analyzed

Complexity

Conditions 21
Paths 1377

Size

Total Lines 115
Code Lines 69

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 21
eloc 69
nc 1377
nop 1
dl 0
loc 115
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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
 * SPDX-License-Identifier: AGPL-3.0-only
5
 * SPDX-FileCopyrightText: Copyright 2007-2016 Zarafa Deutschland GmbH
6
 * SPDX-FileCopyrightText: Copyright 2020-2022 grommunio GmbH
7
 *
8
 * Provides the MOVEITEMS command
9
 */
10
11
class MoveItems extends RequestProcessor {
12
	/**
13
	 * Handles the MoveItems command.
14
	 *
15
	 * @param int $commandCode
16
	 *
17
	 * @return bool
18
	 */
19
	public function Handle($commandCode) {
20
		if (!self::$decoder->getElementStartTag(SYNC_MOVE_MOVES)) {
21
			return false;
22
		}
23
24
		$moves = [];
25
		while (self::$decoder->getElementStartTag(SYNC_MOVE_MOVE)) {
26
			$move = [];
27
			if (self::$decoder->getElementStartTag(SYNC_MOVE_SRCMSGID)) {
28
				$move["srcmsgid"] = self::$decoder->getElementContent();
29
				if (!self::$decoder->getElementEndTag()) {
30
					break;
31
				}
32
			}
33
			if (self::$decoder->getElementStartTag(SYNC_MOVE_SRCFLDID)) {
34
				$move["srcfldid"] = self::$decoder->getElementContent();
35
				if (!self::$decoder->getElementEndTag()) {
36
					break;
37
				}
38
			}
39
			if (self::$decoder->getElementStartTag(SYNC_MOVE_DSTFLDID)) {
40
				$move["dstfldid"] = self::$decoder->getElementContent();
41
				if (!self::$decoder->getElementEndTag()) {
42
					break;
43
				}
44
			}
45
			array_push($moves, $move);
46
47
			if (!self::$decoder->getElementEndTag()) {
48
				return false;
49
			}
50
		}
51
52
		if (!self::$decoder->getElementEndTag()) {
53
			return false;
54
		}
55
56
		self::$encoder->StartWBXML();
57
58
		self::$encoder->startTag(SYNC_MOVE_MOVES);
59
60
		$operationResults = [];
61
		$operationCounter = 0;
62
		$operationTotal = count($moves);
63
		foreach ($moves as $move) {
64
			++$operationCounter;
65
			self::$encoder->startTag(SYNC_MOVE_RESPONSE);
66
			self::$encoder->startTag(SYNC_MOVE_SRCMSGID);
67
			self::$encoder->content($move["srcmsgid"]);
68
			self::$encoder->endTag();
69
70
			$status = SYNC_MOVEITEMSSTATUS_SUCCESS;
71
			$result = false;
72
73
			try {
74
				$sourceBackendFolderId = self::$deviceManager->GetBackendIdForFolderId($move["srcfldid"]);
75
76
				// if the source folder is an additional folder the backend has to be setup correctly
77
				if (!self::$backend->Setup(GSync::GetAdditionalSyncFolderStore($sourceBackendFolderId))) {
78
					throw new StatusException(sprintf("HandleMoveItems() could not Setup() the backend for folder id %s/%s", $move["srcfldid"], $sourceBackendFolderId), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
79
				}
80
81
				$importer = self::$backend->GetImporter($sourceBackendFolderId);
82
				if ($importer === false) {
83
					throw new StatusException(sprintf("HandleMoveItems() could not get an importer for folder id %s/%s", $move["srcfldid"], $sourceBackendFolderId), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
84
				}
85
86
				// get saved SyncParameters of the source folder
87
				$spa = self::$deviceManager->GetStateManager()->GetSynchedFolderState($move["srcfldid"]);
88
				if (!$spa->HasSyncKey()) {
89
					throw new StatusException(sprintf("MoveItems(): Source folder id '%s' is not fully synchronized. Unable to perform operation.", $move["srcfldid"]), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
90
				}
91
92
				$importer->ConfigContentParameters($spa->GetCPO());
93
94
				$result = $importer->ImportMessageMove($move["srcmsgid"], self::$deviceManager->GetBackendIdForFolderId($move["dstfldid"]));
95
				// We discard the standard importer state for now.
96
			}
97
			catch (StatusException $stex) {
98
				if ($stex->getCode() == SYNC_STATUS_FOLDERHIERARCHYCHANGED) { // same as SYNC_FSSTATUS_CODEUNKNOWN
99
					$status = SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID;
100
				}
101
				else {
102
					$status = $stex->getCode();
103
				}
104
			}
105
106
			if ($operationCounter % 10 == 0) {
107
				self::$topCollector->AnnounceInformation(sprintf("Moved %d objects out of %d", $operationCounter, $operationTotal));
108
			}
109
110
			// save the operation result
111
			if (!isset($operationResults[$status])) {
112
				$operationResults[$status] = 0;
113
			}
114
			++$operationResults[$status];
115
116
			self::$encoder->startTag(SYNC_MOVE_STATUS);
117
			self::$encoder->content($status);
118
			self::$encoder->endTag();
119
120
			self::$encoder->startTag(SYNC_MOVE_DSTMSGID);
121
			self::$encoder->content(($result !== false) ? $result : $move["srcmsgid"]);
122
			self::$encoder->endTag();
123
			self::$encoder->endTag();
124
		}
125
126
		self::$topCollector->AnnounceInformation(sprintf("Moved %d - Codes", $operationTotal), true);
127
		foreach ($operationResults as $status => $occurrences) {
128
			self::$topCollector->AnnounceInformation(sprintf("%dx%d", $occurrences, $status), true);
129
		}
130
131
		self::$encoder->endTag();
132
133
		return true;
134
	}
135
}
136