Passed
Pull Request — master (#314)
by korelstar
02:14
created

NotesService::get()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 3
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 2
1
<?php
2
/**
3
 * Nextcloud - Notes
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Bernhard Posselt <[email protected]>
9
 * @copyright Bernhard Posselt 2012, 2014
10
 */
11
12
namespace OCA\Notes\Service;
13
14
use OCP\Files\FileInfo;
15
use OCP\IL10N;
16
use OCP\Files\IRootFolder;
17
use OCP\Files\Folder;
18
use OCP\ILogger;
19
use OCP\Encryption\Exceptions\GenericEncryptionException;
20
use OCA\Notes\Db\Note;
21
use OCA\Notes\Service\SettingsService;
22
use OCP\IConfig;
23
use OCP\IUserSession;
24
25
26
/**
27
 * Class NotesService
28
 *
29
 * @package OCA\Notes\Service
30
 */
31
class NotesService {
32
33
    private $l10n;
34
    private $root;
35
    private $logger;
36
    private $config;
37
    private $settings;
38
    private $appName;
39
40
	/**
41
	 * @param IRootFolder $root
42
	 * @param IL10N $l10n
43
	 * @param ILogger $logger
44
	 * @param IConfig $config
45
	 * @param \OCA\Notes\Service\SettingsService $settings
46
	 * @param String $appName
47
	 */
48
    public function __construct (IRootFolder $root, IL10N $l10n, ILogger $logger, IConfig $config, SettingsService $settings, $appName) {
0 ignored issues
show
Coding Style introduced by
Expected "function abc(...)"; found "function abc (...)"
Loading history...
Coding Style introduced by
Expected 0 spaces before opening parenthesis; 1 found
Loading history...
49
        $this->root = $root;
50
        $this->l10n = $l10n;
51
        $this->logger = $logger;
52
        $this->config = $config;
53
        $this->settings = $settings;
54
        $this->appName = $appName;
55
    }
56
57
58
    /**
59
     * @param string $userId
60
     * @return array with all notes in the current directory
61
     */
62
    public function getAll ($userId, $onlyMeta=false) {
0 ignored issues
show
Coding Style introduced by
Expected "function abc(...)"; found "function abc (...)"
Loading history...
Coding Style introduced by
Expected 0 spaces before opening parenthesis; 1 found
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$onlyMeta" and equals sign; expected 1 but found 0
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$onlyMeta"; expected 1 but found 0
Loading history...
63
        $notesFolder = $this->getFolderForUser($userId);
64
        $notes = $this->gatherNoteFiles($notesFolder);
65
        $filesById = [];
66
        foreach($notes as $note) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after FOREACH keyword; 0 found
Loading history...
67
            $filesById[$note->getId()] = $note;
68
        }
69
        $tagger = \OC::$server->getTagManager()->load('files');
70
        if($tagger===null) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
71
            $tags = [];
72
        } else {
73
            $tags = $tagger->getTagsForObjects(array_keys($filesById));
74
        }
75
76
        $notes = [];
77
        foreach($filesById as $id=>$file) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after FOREACH keyword; 0 found
Loading history...
Coding Style introduced by
Expected 1 space before "=>"; 0 found
Loading history...
Coding Style introduced by
Expected 1 space after "=>"; 0 found
Loading history...
78
            $notes[] = $this->getNote($file, $notesFolder, array_key_exists($id, $tags) ? $tags[$id] : [], $onlyMeta);
79
        }
80
81
        return $notes;
82
    }
83
84
85
    /**
86
     * Used to get a single note by id
87
     * @param int $id the id of the note to get
88
     * @param string $userId
89
     * @throws NoteDoesNotExistException if note does not exist
90
     * @return Note
91
     */
92
    public function get ($id, $userId) {
0 ignored issues
show
Coding Style introduced by
Expected "function abc(...)"; found "function abc (...)"
Loading history...
Coding Style introduced by
Expected 0 spaces before opening parenthesis; 1 found
Loading history...
93
        $folder = $this->getFolderForUser($userId);
94
        return $this->getNote($this->getFileById($folder, $id), $folder, $this->getTags($id));
95
    }
96
97
    private function getTags ($id) {
0 ignored issues
show
Coding Style introduced by
Expected "function abc(...)"; found "function abc (...)"
Loading history...
Coding Style introduced by
Expected 0 spaces before opening parenthesis; 1 found
Loading history...
98
        $tagger = \OC::$server->getTagManager()->load('files');
99
        if($tagger===null) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
100
            $tags = [];
101
        } else {
102
            $tags = $tagger->getTagsForObjects([$id]);
103
        }
104
        return array_key_exists($id, $tags) ? $tags[$id] : [];
105
    }
106
107
    private function getNote($file, $notesFolder, $tags=[], $onlyMeta=false) {
0 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$tags" and equals sign; expected 1 but found 0
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$tags"; expected 1 but found 0
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$onlyMeta" and equals sign; expected 1 but found 0
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$onlyMeta"; expected 1 but found 0
Loading history...
108
        $id = $file->getId();
109
        try {
110
            $note = Note::fromFile($file, $notesFolder, $tags, $onlyMeta);
111
        } catch(GenericEncryptionException $e) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after CATCH keyword; 0 found
Loading history...
112
            $note = Note::fromException($this->l10n->t('Encryption Error').': ('.$file->getName().') '.$e->getMessage(), $file, $notesFolder, array_key_exists($id, $tags) ? $tags[$id] : []);
113
        } catch(\Exception $e) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after CATCH keyword; 0 found
Loading history...
114
            $note = Note::fromException($this->l10n->t('Error').': ('.$file->getName().') '.$e->getMessage(), $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) {
0 ignored issues
show
Coding Style introduced by
Expected "function abc(...)"; found "function abc (...)"
Loading history...
Coding Style introduced by
Expected 0 spaces before opening parenthesis; 1 found
Loading history...
127
        $title = $this->l10n->t('New note');
128
        $folder = $this->getFolderForUser($userId);
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->generateFileName($folder, $title, $this->settings->get($userId, 'fileSuffix'), -1);
134
        $file = $folder->newFile($path);
135
136
        // If server-side encryption is activated, the server creates an empty file without signature
137
        // which leads to an GenericEncryptionException('Missing Signature') afterwards.
138
        // Saving a space-char (and removing it later) is a working work-around.
139
        $file->putContent(' ');
140
141
        return $this->getNote($file, $folder);
142
    }
143
144
145
    /**
146
     * Updates a note. Be sure to check the returned note since the title is
147
     * dynamically generated and filename conflicts are resolved
148
     * @param int $id the id of the note used to update
149
     * @param string|null $content the content which will be written into the note
150
     * the title is generated from the first line of the content
151
     * @param string|null $category the category in which the note should be saved
152
     * @param int $mtime time of the note modification (optional)
153
     * @throws NoteDoesNotExistException if note does not exist
154
     * @return \OCA\Notes\Db\Note the updated note
155
     */
156
    public function update ($id, $content, $userId, $category=null, $mtime=0) {
0 ignored issues
show
Coding Style introduced by
Expected "function abc(...)"; found "function abc (...)"
Loading history...
Coding Style introduced by
Expected 0 spaces before opening parenthesis; 1 found
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$category" and equals sign; expected 1 but found 0
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$category"; expected 1 but found 0
Loading history...
Coding Style introduced by
Incorrect spacing between argument "$mtime" and equals sign; expected 1 but found 0
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$mtime"; expected 1 but found 0
Loading history...
157
        $notesFolder = $this->getFolderForUser($userId);
158
        $file = $this->getFileById($notesFolder, $id);
159
        $title = $this->getSafeTitleFromContent( $content===null ? $file->getContent() : $content );
160
161
162
        // rename/move file with respect to title/category
163
        // this can fail if access rights are not sufficient or category name is illegal
164
        try {
165
            $currentFilePath = $this->root->getFullPath($file->getPath());
166
            $currentBasePath = pathinfo($currentFilePath, PATHINFO_DIRNAME);
167
            $fileSuffix = '.' . pathinfo($file->getName(), PATHINFO_EXTENSION);
168
169
            // detect (new) folder path based on category name
170
            if($category===null) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
171
                $basePath = $currentBasePath;
172
            } else {
173
                $basePath = $notesFolder->getPath();
174
                if(!empty($category)) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
175
                    // sanitise path
176
                    $cats = explode('/', $category);
177
                    $cats = array_map([$this, 'sanitisePath'], $cats);
178
                    $cats = array_filter($cats, function($str) { return !empty($str); });
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
Coding Style introduced by
Opening brace must be the last content on the line
Loading history...
Coding Style introduced by
It is generally recommended to place each PHP statement on a line by itself.

Let’s take a look at an example:

// Bad
$a = 5; $b = 6; $c = 7;

// Good
$a = 5;
$b = 6;
$c = 7;
Loading history...
179
                    $basePath .= '/'.implode('/', $cats);
180
                }
181
            }
182
            $folder = $this->getOrCreateFolder($basePath);
183
184
            // assemble new file path
185
            $newFilePath = $basePath . '/' . $this->generateFileName($folder, $title, $fileSuffix, $id);
186
187
            // if the current path is not the new path, the file has to be renamed
188
            if($currentFilePath !== $newFilePath) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
189
                $file->move($newFilePath);
190
            }
191
            if($currentBasePath !== $basePath) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
192
                $this->deleteEmptyFolder($notesFolder, $this->root->get($currentBasePath));
193
            }
194
        } catch(\OCP\Files\NotPermittedException $e) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after CATCH keyword; 0 found
Loading history...
195
            $this->logger->error('Moving note '.$id.' ('.$title.') to the desired target is not allowed. Please check the note\'s target category ('.$category.').', ['app' => $this->appName]);
196
        } catch(\Exception $e) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after CATCH keyword; 0 found
Loading history...
197
            $this->logger->error('Moving note '.$id.' ('.$title.') to the desired target has failed with a '.get_class($e).': '.$e->getMessage(), ['app' => $this->appName]);
198
        }
199
200
        if($content !== null) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
201
            $file->putContent($content);
202
        }
203
204
        if($mtime) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
205
            $file->touch($mtime);
206
        }
207
208
        return $this->getNote($file, $notesFolder, $this->getTags($id));
209
    }
210
211
    /**
212
     * Set or unset a note as favorite.
213
     * @param int $id the id of the note used to update
214
     * @param boolean $favorite whether the note should be a favorite or not
215
     * @throws NoteDoesNotExistException if note does not exist
216
     * @return boolean the new favorite state of the note
217
     */
218
    public function favorite ($id, $favorite, $userId){
0 ignored issues
show
Coding Style introduced by
Expected "function abc(...)"; found "function abc (...)"
Loading history...
Coding Style introduced by
Expected 0 spaces before opening parenthesis; 1 found
Loading history...
Coding Style introduced by
Expected 1 space before opening brace; found 0
Loading history...
219
        $folder = $this->getFolderForUser($userId);
220
        $file = $this->getFileById($folder, $id);
221
        if(!$this->isNote($file)) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
222
            throw new NoteDoesNotExistException();
223
        }
224
        $tagger = \OC::$server->getTagManager()->load('files');
225
        if($favorite)
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
226
            $tagger->addToFavorites($id);
227
        else
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after ELSE keyword; newline found
Loading history...
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
228
            $tagger->removeFromFavorites($id);
229
230
        $tags = $tagger->getTagsForObjects([$id]);
231
        return array_key_exists($id, $tags) && in_array(\OC\Tags::TAG_FAVORITE, $tags[$id]);
0 ignored issues
show
Bug introduced by
The type OC\Tags was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
232
    }
233
234
235
    /**
236
     * Deletes a note
237
     * @param int $id the id of the note which should be deleted
238
     * @param string $userId
239
     * @throws NoteDoesNotExistException if note does not
240
     * exist
241
     */
242
    public function delete ($id, $userId) {
0 ignored issues
show
Coding Style introduced by
Expected "function abc(...)"; found "function abc (...)"
Loading history...
Coding Style introduced by
Expected 0 spaces before opening parenthesis; 1 found
Loading history...
243
        $notesFolder = $this->getFolderForUser($userId);
244
        $file = $this->getFileById($notesFolder, $id);
245
        $parent = $file->getParent();
246
        $file->delete();
247
        $this->deleteEmptyFolder($notesFolder, $parent);
248
    }
249
250
    // removes characters that are illegal in a file or folder name on some operating systems
251
    private function sanitisePath($str) {
252
        // remove characters which are illegal on Windows (includes illegal characters on Unix/Linux)
253
        // prevents also directory traversal by eliminiating slashes
254
        // see also \OC\Files\Storage\Common::verifyPosixPath(...)
255
        $str = str_replace(['*', '|', '/', '\\', ':', '"', '<', '>', '?'], '', $str);
256
257
        // if mysql doesn't support 4byte UTF-8, then remove those characters
258
        // see \OC\Files\Storage\Common::verifyPath(...)
259
        if (!\OC::$server->getDatabaseConnection()->supports4ByteText()) {
260
            $str = preg_replace('%(?:
261
                \xF0[\x90-\xBF][\x80-\xBF]{2}      # planes 1-3
262
              | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
263
              | \xF4[\x80-\x8F][\x80-\xBF]{2}      # plane 16
264
              )%xs', '', $str);
265
        }
266
267
        // prevent file to be hidden
268
        $str = preg_replace("/^[\. ]+/mu", "", $str);
269
        return trim($str);
270
    }
271
272
    private function getSafeTitleFromContent($content) {
273
        // prepare content: remove markdown characters and empty spaces
274
        $content = preg_replace("/^\s*[*+-]\s+/mu", "", $content); // list item
275
        $content = preg_replace("/^#+\s+(.*?)\s*#*$/mu", "$1", $content); // headline
276
        $content = preg_replace("/^(=+|-+)$/mu", "", $content); // separate line for headline
277
        $content = preg_replace("/(\*+|_+)(.*?)\\1/mu", "$2", $content); // emphasis
278
279
        // sanitize: prevent directory traversal, illegal characters and unintended file names
280
        $content = $this->sanitisePath($content);
281
282
        // generate title from the first line of the content
283
        $splitContent = preg_split("/\R/u", $content, 2);
284
        $title = trim($splitContent[0]);
285
286
        // ensure that title is not empty
287
        if(empty($title)) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
288
            $title = $this->l10n->t('New note');
289
        }
290
291
        // using a maximum of 100 chars should be enough
292
        $title = mb_substr($title, 0, 100, "UTF-8");
293
294
        return $title;
295
    }
296
297
    /**
298
     * @param Folder $folder
299
     * @param int $id
300
     * @throws NoteDoesNotExistException
301
     * @return \OCP\Files\File
302
     */
303
    private function getFileById ($folder, $id) {
0 ignored issues
show
Coding Style introduced by
Expected "function abc(...)"; found "function abc (...)"
Loading history...
Coding Style introduced by
Expected 0 spaces before opening parenthesis; 1 found
Loading history...
304
        $file = $folder->getById($id);
305
306
        if(count($file) <= 0 || !$this->isNote($file[0])) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
307
            throw new NoteDoesNotExistException();
308
        }
309
        return $file[0];
310
    }
311
312
    /**
313
     * @param string $userId the user id
314
     * @return boolean true if folder is accessible, or Exception otherwise
315
     */
316
    public function checkNotesFolder($userId) {
317
        $this->getFolderForUser($userId);
318
        return true;
319
    }
320
321
    /**
322
     * @param string $userId the user id
323
     * @return Folder
324
     */
325
    private function getFolderForUser ($userId) {
0 ignored issues
show
Coding Style introduced by
Expected "function abc(...)"; found "function abc (...)"
Loading history...
Coding Style introduced by
Expected 0 spaces before opening parenthesis; 1 found
Loading history...
326
        $path = '/' . $userId . '/files/' . $this->settings->get($userId, 'notesPath');
327
        try {
328
            $folder = $this->getOrCreateFolder($path);
329
        } catch(\Exception $e) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after CATCH keyword; 0 found
Loading history...
330
            throw new NotesFolderException($path);
331
        }
332
        return $folder;
333
    }
334
335
336
    /**
337
     * Finds a folder and creates it if non-existent
338
     * @param string $path path to the folder
339
     * @return Folder
340
     */
341
    private function getOrCreateFolder($path) {
342
        if ($this->root->nodeExists($path)) {
343
            $folder = $this->root->get($path);
344
        } else {
345
            $folder = $this->root->newFolder($path);
346
        }
347
        return $folder;
348
    }
349
350
    /*
351
     * Delete a folder and it's parent(s) if it's/they're empty
352
     * @param Folder root folder for notes
353
     * @param Folder folder to delete
354
     */
355
    private function deleteEmptyFolder(Folder $notesFolder, Folder $folder) {
356
        $content = $folder->getDirectoryListing();
357
        $isEmpty = !count($content);
358
        $isNotesFolder = $folder->getPath()===$notesFolder->getPath();
359
        if($isEmpty && !$isNotesFolder) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
360
            $this->logger->info('Deleting empty category folder '.$folder->getPath(), ['app' => $this->appName]);
361
            $parent = $folder->getParent();
362
            $folder->delete();
363
            $this->deleteEmptyFolder($notesFolder, $parent);
364
        }
365
    }
366
367
    /**
368
     * get path of file and the title.txt and check if they are the same
369
     * file. If not the title needs to be renamed
370
     *
371
     * @param Folder $folder a folder to the notes directory
372
     * @param string $title the filename which should be used
373
     * @param string $suffix the suffix (incl. dot) which should be used
374
     * @param int $id the id of the note for which the title should be generated
375
     * used to see if the file itself has the title and not a different file for
376
     * checking for filename collisions
377
     * @return string the resolved filename to prevent overwriting different
378
     * files with the same title
379
     */
380
    private function generateFileName (Folder $folder, $title, $suffix, $id) {
0 ignored issues
show
Coding Style introduced by
Expected "function abc(...)"; found "function abc (...)"
Loading history...
Coding Style introduced by
Expected 0 spaces before opening parenthesis; 1 found
Loading history...
381
        $path = $title . $suffix;
382
383
        // if file does not exist, that name has not been taken. Similar we don't
384
        // need to handle file collisions if it is the filename did not change
385
        if (!$folder->nodeExists($path) || $folder->get($path)->getId() === $id) {
386
            return $path;
387
        } else {
388
            // increments name (2) to name (3)
389
            $match = preg_match('/\((?P<id>\d+)\)$/u', $title, $matches);
390
            if($match) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
391
                $newId = ((int) $matches['id']) + 1;
392
                $newTitle = preg_replace('/(.*)\s\((\d+)\)$/u',
393
                    '$1 (' . $newId . ')', $title);
394
            } else {
395
                $newTitle = $title . ' (2)';
396
            }
397
            return $this->generateFileName($folder, $newTitle, $suffix, $id);
398
        }
399
    }
400
401
	/**
402
	 * gather note files in given directory and all subdirectories
403
	 * @param Folder $folder
404
	 * @return array
405
	 */
406
	private function gatherNoteFiles ($folder) {
0 ignored issues
show
Coding Style introduced by
Expected "function abc(...)"; found "function abc (...)"
Loading history...
Coding Style introduced by
Expected 0 spaces before opening parenthesis; 1 found
Loading history...
407
		$notes = [];
408
		$nodes = $folder->getDirectoryListing();
409
		foreach($nodes as $node) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after FOREACH keyword; 0 found
Loading history...
410
			if($node->getType() === FileInfo::TYPE_FOLDER) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
411
				$notes = array_merge($notes, $this->gatherNoteFiles($node));
412
				continue;
413
			}
414
			if($this->isNote($node)) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
415
				$notes[] = $node;
416
			}
417
		}
418
		return $notes;
419
	}
420
421
422
    /**
423
     * test if file is a note
424
     *
425
     * @param \OCP\Files\File $file
426
     * @return bool
427
     */
428
    private function isNote($file) {
429
        $allowedExtensions = ['txt', 'org', 'markdown', 'md', 'note'];
430
431
        if($file->getType() !== 'file') return false;
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
432
433
        $ext = pathinfo($file->getName(), PATHINFO_EXTENSION);
434
        $iext = strtolower($ext);
435
        if(!in_array($iext, $allowedExtensions)) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after IF keyword; 0 found
Loading history...
436
            return false;
437
        }
438
        return true;
439
    }
440
441
}
442