Passed
Pull Request — master (#456)
by korelstar
02:46
created

NotesService::__construct()   A

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