NotesService::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 8
c 2
b 0
f 0
dl 0
loc 18
rs 10
cc 1
nc 1
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace OCA\Notes\Service;
4
5
use OCP\Encryption\Exceptions\GenericEncryptionException;
6
use OCP\Files\File;
7
use OCP\Files\Folder;
8
use OCP\Files\IRootFolder;
9
use OCP\IConfig;
10
use OCP\IL10N;
11
use OCP\ILogger;
12
use OCP\ITagManager;
13
14
use OCA\Notes\Db\Note;
15
use OCA\Notes\Service\SettingsService;
16
17
/**
18
 * Class NotesService
19
 *
20
 * @package OCA\Notes\Service
21
 */
22
class NotesService {
23
24
	private $l10n;
25
	private $root;
26
	private $logger;
27
	private $config;
28
	private $tags;
29
	private $settings;
30
	private $noteUtil;
31
	private $appName;
32
33
	/**
34
	 * @param IRootFolder $root
35
	 * @param IL10N $l10n
36
	 * @param ILogger $logger
37
	 * @param IConfig $config
38
	 * @param ITagManager $tagManager
39
	 * @param SettingsService $settings
40
	 * @param NoteUtil $noteUtil
41
	 * @param String $appName
42
	 */
43
	public function __construct(
44
		IRootFolder $root,
45
		IL10N $l10n,
46
		ILogger $logger,
47
		IConfig $config,
48
		ITagManager $tagManager,
49
		SettingsService $settings,
50
		NoteUtil $noteUtil,
51
		$appName
52
	) {
53
		$this->root = $root;
54
		$this->l10n = $l10n;
55
		$this->logger = $logger;
56
		$this->config = $config;
57
		$this->tags = $tagManager->load('files');
58
		$this->settings = $settings;
59
		$this->noteUtil = $noteUtil;
60
		$this->appName = $appName;
61
	}
62
63
64
	/**
65
	 * @param string $userId
66
	 * @return array with all notes in the current directory
67
	 */
68
	public function getAll($userId, $onlyMeta = false) {
69
		$notesFolder = $this->getFolderForUser($userId);
70
		$notes = $this->noteUtil->gatherNoteFiles($notesFolder);
71
		$filesById = [];
72
		foreach ($notes as $note) {
73
			$filesById[$note->getId()] = $note;
74
		}
75
		$tags = $this->tags->getTagsForObjects(array_keys($filesById));
76
77
		$notes = [];
78
		foreach ($filesById as $id => $file) {
79
			$noteTags = is_array($tags) && array_key_exists($id, $tags) ? $tags[$id] : [];
80
			$notes[] = $this->getNote($file, $notesFolder, $noteTags, $onlyMeta);
81
		}
82
83
		return $notes;
84
	}
85
86
87
	/**
88
	 * Used to get a single note by id
89
	 * @param int $id the id of the note to get
90
	 * @param string $userId
91
	 * @throws NoteDoesNotExistException if note does not exist
92
	 * @return Note
93
	 */
94
	public function get($id, $userId, $onlyMeta = false) : Note {
95
		$folder = $this->getFolderForUser($userId);
96
		return $this->getNote($this->getFileById($folder, $id), $folder, $this->getTags($id), $onlyMeta);
97
	}
98
99
	private function getTags($id) {
100
		$tags = $this->tags->getTagsForObjects([$id]);
101
		return is_array($tags) && array_key_exists($id, $tags) ? $tags[$id] : [];
102
	}
103
104
	private function getNote(File $file, Folder $notesFolder, $tags = [], $onlyMeta = false) : Note {
105
		$id = $file->getId();
106
		try {
107
			$note = Note::fromFile($file, $notesFolder, $tags, $onlyMeta);
108
		} catch (GenericEncryptionException $e) {
109
			$message = $this->l10n->t('Encryption Error').': ('.$file->getName().') '.$e->getMessage();
110
			$note = Note::fromException($message, $file, $notesFolder, array_key_exists($id, $tags) ? $tags[$id] : []);
111
		} catch (\Exception $e) {
112
			$message = $this->l10n->t('Error').': ('.$file->getName().') '.$e->getMessage();
113
			$note = Note::fromException($message, $file, $notesFolder, array_key_exists($id, $tags) ? $tags[$id] : []);
114
		}
115
		return $note;
116
	}
117
118
119
	/**
120
	 * Creates a note and returns the empty note
121
	 * @param string $userId
122
	 * @see update for setting note content
123
	 * @return Note the newly created note
124
	 */
125
	public function create($userId) : Note {
126
		$title = $this->l10n->t('New note');
127
		$folder = $this->getFolderForUser($userId);
128
		$this->noteUtil->ensureSufficientStorage($folder, 1);
129
130
		// check new note exists already and we need to number it
131
		// pass -1 because no file has id -1 and that will ensure
132
		// to only return filenames that dont yet exist
133
		$path = $this->noteUtil->generateFileName($folder, $title, $this->settings->get($userId, 'fileSuffix'), -1);
134
		$file = $folder->newFile($path);
135
136
		// try to write some content
137
		try {
138
			// If server-side encryption is activated, the server creates an empty file without signature
139
			// which leads to an GenericEncryptionException('Missing Signature') afterwards.
140
			// Saving a space-char (and removing it later) is a working work-around.
141
			$file->putContent(' ');
142
		} catch (\Throwable $e) {
143
			// if writing the content fails, we have to roll back the note creation
144
			$this->delete($file->getId(), $userId);
145
			throw $e;
146
		}
147
148
		return $this->getNote($file, $folder);
149
	}
150
151
152
	/**
153
	 * Updates a note. Be sure to check the returned note since the title is
154
	 * dynamically generated and filename conflicts are resolved
155
	 * @param int $id the id of the note used to update
156
	 * @param string|null $content the content which will be written into the note
157
	 * the title is generated from the first line of the content
158
	 * @param string|null $category the category in which the note should be saved
159
	 * @param int $mtime time of the note modification (optional)
160
	 * @throws NoteDoesNotExistException if note does not exist
161
	 * @return \OCA\Notes\Db\Note the updated note
162
	 */
163
	public function update($id, $content, $userId, $category = null, $mtime = 0) : Note {
164
		$notesFolder = $this->getFolderForUser($userId);
165
		$file = $this->getFileById($notesFolder, $id);
166
		$title = $this->noteUtil->getSafeTitleFromContent($content===null ? $file->getContent() : $content);
167
168
		// rename/move file with respect to title/category
169
		// this can fail if access rights are not sufficient or category name is illegal
170
		try {
171
			$this->noteUtil->moveNote($notesFolder, $file, $category, $title);
172
		} catch (\OCP\Files\NotPermittedException $e) {
173
			$err = 'Moving note '.$id.' ('.$title.') to the desired target is not allowed.'
174
				.' Please check the note\'s target category ('.$category.').';
175
			$this->logger->error($err, ['app' => $this->appName]);
176
		} catch (\Exception $e) {
177
			$err = 'Moving note '.$id.' ('.$title.') to the desired target has failed '
178
				.'with a '.get_class($e).': '.$e->getMessage();
179
			$this->logger->error($err, ['app' => $this->appName]);
180
		}
181
182
		if ($content !== null) {
183
			$this->noteUtil->ensureSufficientStorage($file->getParent(), strlen($content));
184
			$file->putContent($content);
185
		}
186
187
		if ($mtime) {
188
			$file->touch($mtime);
189
		}
190
191
		return $this->getNote($file, $notesFolder, $this->getTags($id));
192
	}
193
194
	/**
195
	 * Set or unset a note as favorite.
196
	 * @param int $id the id of the note used to update
197
	 * @param boolean $favorite whether the note should be a favorite or not
198
	 * @throws NoteDoesNotExistException if note does not exist
199
	 * @return boolean the new favorite state of the note
200
	 */
201
	public function favorite($id, $favorite, $userId) {
202
		$note = $this->get($id, $userId, true);
203
		if ($favorite !== $note->getFavorite()) {
204
			if ($favorite) {
205
				$this->tags->addToFavorites($id);
206
			} else {
207
				$this->tags->removeFromFavorites($id);
208
			}
209
			$note = $this->get($id, $userId, true);
210
		}
211
		return $note->getFavorite();
212
	}
213
214
215
	/**
216
	 * Deletes a note
217
	 * @param int $id the id of the note which should be deleted
218
	 * @param string $userId
219
	 * @throws NoteDoesNotExistException if note does not
220
	 * exist
221
	 */
222
	public function delete($id, $userId) {
223
		$notesFolder = $this->getFolderForUser($userId);
224
		$file = $this->getFileById($notesFolder, $id);
225
		$parent = $file->getParent();
226
		$file->delete();
227
		$this->noteUtil->deleteEmptyFolder($notesFolder, $parent);
228
	}
229
230
	/**
231
	 * @param Folder $folder
232
	 * @param int $id
233
	 * @throws NoteDoesNotExistException
234
	 * @return \OCP\Files\File
235
	 */
236
	private function getFileById(Folder $folder, $id) : File {
237
		$file = $folder->getById($id);
238
239
		if (count($file) <= 0 || !($file[0] instanceof File) || !$this->noteUtil->isNote($file[0])) {
240
			throw new NoteDoesNotExistException();
241
		}
242
		return $file[0];
243
	}
244
245
	/**
246
	 * @param string $userId the user id
247
	 * @return Folder
248
	 */
249
	private function getFolderForUser($userId) : Folder {
250
		// TODO use IRootFolder->getUserFolder()  ?
251
		$path = '/' . $userId . '/files/' . $this->settings->get($userId, 'notesPath');
252
		try {
253
			$folder = $this->noteUtil->getOrCreateFolder($path);
254
		} catch (\Exception $e) {
255
			throw new NotesFolderException($path);
256
		}
257
		return $folder;
258
	}
259
}
260