From 16de16937ef5f0260fd999b282ca23edd98a25be Mon Sep 17 00:00:00 2001 From: korelstar Date: Sat, 25 May 2019 08:15:05 +0200 Subject: [PATCH] code style and lint errors --- .gitignore | 2 + .scrutinizer.yml | 1 + .travis.yml | 3 +- Makefile | 64 +- appinfo/app.php | 19 +- composer.json | 3 +- lib/Controller/Errors.php | 31 +- lib/Controller/NotesApiController.php | 315 +++++----- lib/Controller/NotesController.php | 305 +++++----- lib/Controller/PageController.php | 58 +- lib/Controller/SettingsController.php | 5 +- lib/Db/Meta.php | 18 +- lib/Db/MetaMapper.php | 25 +- lib/Db/Note.php | 170 +++--- lib/Service/MetaService.php | 20 +- lib/Service/NoteDoesNotExistException.php | 12 +- lib/Service/NotesFolderException.php | 10 +- lib/Service/NotesService.php | 679 +++++++++++----------- lib/Service/SettingsService.php | 21 +- phpcs.xml | 32 + 20 files changed, 892 insertions(+), 901 deletions(-) create mode 100644 phpcs.xml diff --git a/.gitignore b/.gitignore index cce3f6c5..9f90f46d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,12 @@ node_modules/ +vendor/ *.log build/ js/ .rvm report clover.xml +composer.lock # just sane ignores .*.sw[po] diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 1bdffeba..0543eeee 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -11,6 +11,7 @@ build: tests: override: - php-scrutinizer-run + - phpcs-run --standard=phpcs.xml appinfo/ lib/ - eslint-run --ext .js,.vue src tools: diff --git a/.travis.yml b/.travis.yml index bcadd8f9..a262abfb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,8 +49,7 @@ script: # - phpunit -c phpunit.integration.xml # build js - - make npm-init + - make init - make lint - - make stylelint - make build-js-production diff --git a/Makefile b/Makefile index 1f524cde..503f214b 100644 --- a/Makefile +++ b/Makefile @@ -9,32 +9,32 @@ appstore_dir=$(build_dir)/appstore package_name=$(app_name) cert_dir=$(HOME)/.nextcloud/certificates -appstore: clean +appstore: clean lint build-js-production mkdir -p $(sign_dir) rsync -a \ - --exclude=.git \ + --exclude=.babelrc.js \ --exclude=build \ - --exclude=.gitignore \ - --exclude=.travis.yml \ - --exclude=.scrutinizer.yml \ - --exclude=CONTRIBUTING.md \ --exclude=composer.json \ --exclude=composer.lock \ --exclude=composer.phar \ - --exclude=.tx \ + --exclude=CONTRIBUTING.md \ + --exclude=.editorconfig \ + --exclude=.eslintrc.js \ + --exclude=.git \ + --exclude=.github \ + --exclude=.gitignore \ --exclude=l10n/no-php \ --exclude=Makefile \ - --exclude=nbproject \ - --exclude=screenshots \ + --exclude=package*.json \ + --exclude=phpcs.xml \ --exclude=phpunit*xml \ + --exclude=.scrutinizer.yml \ + --exclude=src \ + --exclude=.stylelintrc.js \ --exclude=tests \ - --exclude=vendor/bin \ - --exclude=js/node_modules \ - --exclude=js/tests \ - --exclude=js/karma.conf.js \ - --exclude=js/gulpfile.js \ - --exclude=js/bower.json \ - --exclude=js/package.json \ + --exclude=.travis.yml \ + --exclude=.tx \ + --exclude=vendor \ $(project_dir) $(sign_dir) @echo "Signing…" php ../server/occ integrity:sign-app \ @@ -51,7 +51,12 @@ appstore: clean all: dev-setup lint build-js-production test # Dev env management -dev-setup: clean clean-dev npm-init +dev-setup: clean clean-dev init + +init: composer-init npm-init + +composer-init: + composer install npm-init: npm install @@ -84,17 +89,27 @@ test-coverage: npm run test:coverage # Linting -lint: +lint: lint-php lint-js lint-css + +lint-php: + vendor/bin/phpcs --standard=phpcs.xml --runtime-set ignore_warnings_on_exit 1 appinfo/ lib/ + +lint-js: npm run lint -lint-fix: - npm run lint:fix - -# Style linting -stylelint: +lint-css: npm run stylelint -stylelint-fix: +# Fix lint +lint-fix: lint-php-fix lint-js-fix lint-css-fix + +lint-php-fix: + vendor/bin/phpcbf --standard=phpcs.xml appinfo/ lib/ + +lint-js-fix: + npm run lint:fix + +lint-css-fix: npm run stylelint:fix # Cleaning @@ -104,4 +119,5 @@ clean: clean-dev: rm -rf node_modules + rm -rf vendor diff --git a/appinfo/app.php b/appinfo/app.php index 61b167b3..4477c5e6 100644 --- a/appinfo/app.php +++ b/appinfo/app.php @@ -17,14 +17,13 @@ $app = new App('notes'); $container = $app->getContainer(); $container->query('OCP\INavigationManager')->add(function () use ($container) { - $urlGenerator = $container->query('OCP\IURLGenerator'); - $l10n = $container->query('OCP\IL10N'); - return [ - 'id' => 'notes', - 'order' => 10, - 'href' => $urlGenerator->linkToRoute('notes.page.index'), - 'icon' => $urlGenerator->imagePath('notes', 'notes.svg'), - 'name' => $l10n->t('Notes') - ]; + $urlGenerator = $container->query('OCP\IURLGenerator'); + $l10n = $container->query('OCP\IL10N'); + return [ + 'id' => 'notes', + 'order' => 10, + 'href' => $urlGenerator->linkToRoute('notes.page.index'), + 'icon' => $urlGenerator->imagePath('notes', 'notes.svg'), + 'name' => $l10n->t('Notes') + ]; }); - diff --git a/composer.json b/composer.json index cc285efc..b1e1d245 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,6 @@ { "require-dev": { - "christophwurst/nextcloud": "^15.0" + "christophwurst/nextcloud": "^15.0", + "squizlabs/php_codesniffer": "3.*" } } diff --git a/lib/Controller/Errors.php b/lib/Controller/Errors.php index 171bd102..138f05d8 100644 --- a/lib/Controller/Errors.php +++ b/lib/Controller/Errors.php @@ -1,13 +1,4 @@ - * @copyright Bernhard Posselt 2012, 2014 - */ namespace OCA\Notes\Controller; @@ -22,15 +13,15 @@ use OCA\Notes\Service\NoteDoesNotExistException; * @package OCA\Notes\Controller */ trait Errors { - /** - * @param $callback - * @return DataResponse - */ - protected function respond ($callback) { - try { - return new DataResponse($callback()); - } catch(NoteDoesNotExistException $ex) { - return new DataResponse([], Http::STATUS_NOT_FOUND); - } - } + /** + * @param $callback + * @return DataResponse + */ + protected function respond($callback) { + try { + return new DataResponse($callback()); + } catch (NoteDoesNotExistException $ex) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + } } diff --git a/lib/Controller/NotesApiController.php b/lib/Controller/NotesApiController.php index 6766e0e4..9eaf82a4 100644 --- a/lib/Controller/NotesApiController.php +++ b/lib/Controller/NotesApiController.php @@ -1,13 +1,4 @@ - * @copyright Bernhard Posselt 2012, 2014 - */ namespace OCA\Notes\Controller; @@ -28,173 +19,171 @@ use OCA\Notes\Db\Note; */ class NotesApiController extends ApiController { - use Errors; + use Errors; - /** @var NotesService */ - private $service; - /** @var MetaService */ - private $metaService; - /** @var IUserSession */ - private $userSession; + /** @var NotesService */ + private $service; + /** @var MetaService */ + private $metaService; + /** @var IUserSession */ + private $userSession; - /** - * @param string $AppName - * @param IRequest $request - * @param NotesService $service - * @param IUserSession $userSession - */ - public function __construct($AppName, IRequest $request, NotesService $service, MetaService $metaService, IUserSession $userSession) { - parent::__construct($AppName, $request); - $this->service = $service; - $this->metaService = $metaService; - $this->userSession = $userSession; - } + /** + * @param string $AppName + * @param IRequest $request + * @param NotesService $service + * @param IUserSession $userSession + */ + public function __construct($AppName, IRequest $request, NotesService $service, MetaService $metaService, IUserSession $userSession) { + parent::__construct($AppName, $request); + $this->service = $service; + $this->metaService = $metaService; + $this->userSession = $userSession; + } - private function getUID() { - return $this->userSession->getUser()->getUID(); - } + private function getUID() { + return $this->userSession->getUser()->getUID(); + } - /** - * @param Note $note - * @param string[] $exclude the fields that should be removed from the - * notes - * @return Note - */ - private function excludeFields(Note &$note, array $exclude) { - if(count($exclude) > 0) { - foreach ($exclude as $field) { - if(property_exists($note, $field)) { - unset($note->$field); - } - } - } - return $note; - } + /** + * @param Note $note + * @param string[] $exclude the fields that should be removed from the + * notes + * @return Note + */ + private function excludeFields(Note &$note, array $exclude) { + if (count($exclude) > 0) { + foreach ($exclude as $field) { + if (property_exists($note, $field)) { + unset($note->$field); + } + } + } + return $note; + } - /** - * @NoAdminRequired - * @CORS - * @NoCSRFRequired - * - * @param string $exclude - * @return DataResponse - */ - public function index($exclude='', $pruneBefore=0) { - $exclude = explode(',', $exclude); - $now = new \DateTime(); // this must be before loading notes if there are concurrent changes possible - $notes = $this->service->getAll($this->getUID()); - $metas = $this->metaService->updateAll($this->getUID(), $notes); - foreach ($notes as $note) { - $lastUpdate = $metas[$note->getId()]->getLastUpdate(); - if($pruneBefore && $lastUpdate<$pruneBefore) { - $vars = get_object_vars($note); - unset($vars['id']); - $this->excludeFields($note, array_keys($vars)); - } else { - $this->excludeFields($note, $exclude); - } - } - $etag = md5(json_encode($notes)); - if ($this->request->getHeader('If-None-Match') === '"'.$etag.'"') { - return new DataResponse([], Http::STATUS_NOT_MODIFIED); - } - return (new DataResponse($notes)) - ->setLastModified($now) - ->setETag($etag); - } + /** + * @NoAdminRequired + * @CORS + * @NoCSRFRequired + * + * @param string $exclude + * @return DataResponse + */ + public function index($exclude = '', $pruneBefore = 0) { + $exclude = explode(',', $exclude); + $now = new \DateTime(); // this must be before loading notes if there are concurrent changes possible + $notes = $this->service->getAll($this->getUID()); + $metas = $this->metaService->updateAll($this->getUID(), $notes); + foreach ($notes as $note) { + $lastUpdate = $metas[$note->getId()]->getLastUpdate(); + if ($pruneBefore && $lastUpdate<$pruneBefore) { + $vars = get_object_vars($note); + unset($vars['id']); + $this->excludeFields($note, array_keys($vars)); + } else { + $this->excludeFields($note, $exclude); + } + } + $etag = md5(json_encode($notes)); + if ($this->request->getHeader('If-None-Match') === '"'.$etag.'"') { + return new DataResponse([], Http::STATUS_NOT_MODIFIED); + } + return (new DataResponse($notes)) + ->setLastModified($now) + ->setETag($etag); + } - /** - * @NoAdminRequired - * @CORS - * @NoCSRFRequired - * - * @param int $id - * @param string $exclude - * @return DataResponse - */ - public function get($id, $exclude='') { - $exclude = explode(',', $exclude); + /** + * @NoAdminRequired + * @CORS + * @NoCSRFRequired + * + * @param int $id + * @param string $exclude + * @return DataResponse + */ + public function get($id, $exclude = '') { + $exclude = explode(',', $exclude); - return $this->respond(function () use ($id, $exclude) { - $note = $this->service->get($id, $this->getUID()); - $note = $this->excludeFields($note, $exclude); - return $note; - }); - } + return $this->respond(function () use ($id, $exclude) { + $note = $this->service->get($id, $this->getUID()); + $note = $this->excludeFields($note, $exclude); + return $note; + }); + } - /** - * @NoAdminRequired - * @CORS - * @NoCSRFRequired - * - * @param string $content - * @param string $category - * @param int $modified - * @param boolean $favorite - * @return DataResponse - */ - public function create($content, $category=null, $modified=0, $favorite=null) { - return $this->respond(function () use ($content, $category, $modified, $favorite) { - $note = $this->service->create($this->getUID()); - return $this->updateData($note->getId(), $content, $category, $modified, $favorite); - }); - } + /** + * @NoAdminRequired + * @CORS + * @NoCSRFRequired + * + * @param string $content + * @param string $category + * @param int $modified + * @param boolean $favorite + * @return DataResponse + */ + public function create($content, $category = null, $modified = 0, $favorite = null) { + return $this->respond(function () use ($content, $category, $modified, $favorite) { + $note = $this->service->create($this->getUID()); + return $this->updateData($note->getId(), $content, $category, $modified, $favorite); + }); + } - /** - * @NoAdminRequired - * @CORS - * @NoCSRFRequired - * - * @param int $id - * @param string $content - * @param string $category - * @param int $modified - * @param boolean $favorite - * @return DataResponse - */ - public function update($id, $content=null, $category=null, $modified=0, $favorite=null) { - return $this->respond(function () use ($id, $content, $category, $modified, $favorite) { - return $this->updateData($id, $content, $category, $modified, $favorite); - }); - } - - /** - * Updates a note, used by create and update - * @param int $id - * @param string $content - * @param int $modified - * @param boolean $favorite - * @return Note - */ - private function updateData($id, $content, $category, $modified, $favorite) { - if($favorite!==null) { - $this->service->favorite($id, $favorite, $this->getUID()); - } - if($content===null) { - return $this->service->get($id, $this->getUID()); - } else { - return $this->service->update($id, $content, $this->getUID(), $category, $modified); - } - } - - /** - * @NoAdminRequired - * @CORS - * @NoCSRFRequired - * - * @param int $id - * @return DataResponse - */ - public function destroy($id) { - return $this->respond(function () use ($id) { - $this->service->delete($id, $this->getUID()); - return []; - }); - } + /** + * @NoAdminRequired + * @CORS + * @NoCSRFRequired + * + * @param int $id + * @param string $content + * @param string $category + * @param int $modified + * @param boolean $favorite + * @return DataResponse + */ + public function update($id, $content = null, $category = null, $modified = 0, $favorite = null) { + return $this->respond(function () use ($id, $content, $category, $modified, $favorite) { + return $this->updateData($id, $content, $category, $modified, $favorite); + }); + } + /** + * Updates a note, used by create and update + * @param int $id + * @param string|null $content + * @param int $modified + * @param boolean|null $favorite + * @return Note + */ + private function updateData($id, $content, $category, $modified, $favorite) { + if ($favorite!==null) { + $this->service->favorite($id, $favorite, $this->getUID()); + } + if ($content===null) { + return $this->service->get($id, $this->getUID()); + } else { + return $this->service->update($id, $content, $this->getUID(), $category, $modified); + } + } + /** + * @NoAdminRequired + * @CORS + * @NoCSRFRequired + * + * @param int $id + * @return DataResponse + */ + public function destroy($id) { + return $this->respond(function () use ($id) { + $this->service->delete($id, $this->getUID()); + return []; + }); + } } diff --git a/lib/Controller/NotesController.php b/lib/Controller/NotesController.php index 6c40c95c..f6bd076e 100644 --- a/lib/Controller/NotesController.php +++ b/lib/Controller/NotesController.php @@ -1,13 +1,4 @@ - * @copyright Bernhard Posselt 2012, 2014 - */ namespace OCA\Notes\Controller; @@ -27,167 +18,177 @@ use OCA\Notes\Service\SettingsService; */ class NotesController extends Controller { - use Errors; + use Errors; - /** @var NotesService */ - private $notesService; - /** @var SettingsService */ - private $settingsService; - /** @var IConfig */ - private $settings; - /** @var string */ - private $userId; - /** @var IL10N */ - private $l10n; + /** @var NotesService */ + private $notesService; + /** @var SettingsService */ + private $settingsService; + /** @var IConfig */ + private $settings; + /** @var string */ + private $userId; + /** @var IL10N */ + private $l10n; - /** - * @param string $AppName - * @param IRequest $request - * @param NotesService $notesService - * @param SettingsService $settingsService - * @param IConfig $settings - * @param IL10N $l10n - * @param string $UserId - */ - public function __construct($AppName, - IRequest $request, - NotesService $notesService, - SettingsService $settingsService, - IConfig $settings, - IL10N $l10n, - $UserId) { - parent::__construct($AppName, $request); - $this->notesService = $notesService; - $this->settingsService = $settingsService; - $this->settings = $settings; - $this->userId = $UserId; - $this->l10n = $l10n; - } + /** + * @param string $AppName + * @param IRequest $request + * @param NotesService $notesService + * @param SettingsService $settingsService + * @param IConfig $settings + * @param IL10N $l10n + * @param string $UserId + */ + public function __construct( + $AppName, + IRequest $request, + NotesService $notesService, + SettingsService $settingsService, + IConfig $settings, + IL10N $l10n, + $UserId + ) { + parent::__construct($AppName, $request); + $this->notesService = $notesService; + $this->settingsService = $settingsService; + $this->settings = $settings; + $this->userId = $UserId; + $this->l10n = $l10n; + } - /** - * @NoAdminRequired - */ - public function index() { - $notes = $this->notesService->getAll($this->userId, true); - $settings = $this->settingsService->getAll($this->userId); + /** + * @NoAdminRequired + */ + public function index() { + $notes = $this->notesService->getAll($this->userId, true); + $settings = $this->settingsService->getAll($this->userId); - $errorMessage = null; - $lastViewedNote = (int) $this->settings->getUserValue($this->userId, - $this->appName, 'notesLastViewedNote'); - // check if notes folder is accessible - try { - $this->notesService->checkNotesFolder($this->userId); - if($lastViewedNote) { - // check if note exists - try { - $this->notesService->get($lastViewedNote, $this->userId); - } catch(\Exception $ex) { - $this->settings->deleteUserValue($this->userId, $this->appName, 'notesLastViewedNote'); - $lastViewedNote = 0; - $errorMessage = $this->l10n->t('The last viewed note cannot be accessed. ').$ex->getMessage(); - } - } - } catch(\Exception $e) { - $errorMessage = $this->l10n->t('The notes folder is not accessible: %s', $e->getMessage()); - } + $errorMessage = null; + $lastViewedNote = (int) $this->settings->getUserValue( + $this->userId, + $this->appName, + 'notesLastViewedNote' + ); + // check if notes folder is accessible + try { + $this->notesService->checkNotesFolder($this->userId); + if ($lastViewedNote) { + // check if note exists + try { + $this->notesService->get($lastViewedNote, $this->userId); + } catch (\Exception $ex) { + $this->settings->deleteUserValue($this->userId, $this->appName, 'notesLastViewedNote'); + $lastViewedNote = 0; + $errorMessage = $this->l10n->t('The last viewed note cannot be accessed. ').$ex->getMessage(); + } + } + } catch (\Exception $e) { + $errorMessage = $this->l10n->t('The notes folder is not accessible: %s', $e->getMessage()); + } - return new DataResponse([ - 'notes' => $notes, - 'settings' => $settings, - 'lastViewedNote' => $lastViewedNote, - 'errorMessage' => $errorMessage, - ]); - } + return new DataResponse([ + 'notes' => $notes, + 'settings' => $settings, + 'lastViewedNote' => $lastViewedNote, + 'errorMessage' => $errorMessage, + ]); + } - /** - * @NoAdminRequired - * - * @param int $id - * @return DataResponse - */ - public function get($id) { - // save the last viewed note - $this->settings->setUserValue( - $this->userId, $this->appName, 'notesLastViewedNote', $id - ); + /** + * @NoAdminRequired + * + * @param int $id + * @return DataResponse + */ + public function get($id) { + // save the last viewed note + $this->settings->setUserValue( + $this->userId, + $this->appName, + 'notesLastViewedNote', + $id + ); - return $this->respond(function () use ($id) { - return $this->notesService->get($id, $this->userId); - }); - } + return $this->respond(function () use ($id) { + return $this->notesService->get($id, $this->userId); + }); + } - /** - * @NoAdminRequired - * - * @param string $content - */ - public function create($content='', $category=null) { - $note = $this->notesService->create($this->userId); - $note = $this->notesService->update( - $note->getId(), $content, $this->userId, $category - ); - return new DataResponse($note); - } + /** + * @NoAdminRequired + * + * @param string $content + */ + public function create($content = '', $category = null) { + $note = $this->notesService->create($this->userId); + $note = $this->notesService->update( + $note->getId(), + $content, + $this->userId, + $category + ); + return new DataResponse($note); + } - /** - * @NoAdminRequired - * - * @param int $id - * @param string $content - * @return DataResponse - */ - public function update($id, $content) { - return $this->respond(function () use ($id, $content) { - return $this->notesService->update($id, $content, $this->userId); - }); - } + /** + * @NoAdminRequired + * + * @param int $id + * @param string $content + * @return DataResponse + */ + public function update($id, $content) { + return $this->respond(function () use ($id, $content) { + return $this->notesService->update($id, $content, $this->userId); + }); + } - /** - * @NoAdminRequired - * - * @param int $id - * @param string $category - * @return DataResponse - */ - public function category($id, $category) { - return $this->respond(function () use ($id, $category) { - $note = $this->notesService->update($id, null, $this->userId, $category); - return $note->category; - }); - } + /** + * @NoAdminRequired + * + * @param int $id + * @param string $category + * @return DataResponse + */ + public function category($id, $category) { + return $this->respond(function () use ($id, $category) { + $note = $this->notesService->update($id, null, $this->userId, $category); + return $note->category; + }); + } - /** - * @NoAdminRequired - * - * @param int $id - * @param boolean $favorite - * @return DataResponse - */ - public function favorite($id, $favorite) { - return $this->respond(function () use ($id, $favorite) { - return $this->notesService->favorite($id, $favorite, $this->userId); - }); - } + /** + * @NoAdminRequired + * + * @param int $id + * @param boolean $favorite + * @return DataResponse + */ + public function favorite($id, $favorite) { + return $this->respond(function () use ($id, $favorite) { + return $this->notesService->favorite($id, $favorite, $this->userId); + }); + } - /** - * @NoAdminRequired - * - * @param int $id - * @return DataResponse - */ - public function destroy($id) { - return $this->respond(function () use ($id) { - $this->notesService->delete($id, $this->userId); - return []; - }); - } - + /** + * @NoAdminRequired + * + * @param int $id + * @return DataResponse + */ + public function destroy($id) { + return $this->respond(function () use ($id) { + $this->notesService->delete($id, $this->userId); + return []; + }); + } } diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index ac7625ee..6d304fea 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -1,13 +1,4 @@ - * @copyright Bernhard Posselt 2012, 2014 - */ namespace OCA\Notes\Controller; @@ -23,33 +14,32 @@ use OCP\IRequest; */ class PageController extends Controller { - /** - * @param string $AppName - * @param IRequest $request - */ - public function __construct($AppName, IRequest $request) { - parent::__construct($AppName, $request); - } + /** + * @param string $AppName + * @param IRequest $request + */ + public function __construct($AppName, IRequest $request) { + parent::__construct($AppName, $request); + } - /** - * @NoAdminRequired - * @NoCSRFRequired - * - * @return TemplateResponse - */ - public function index() { - $response = new TemplateResponse( - $this->appName, - 'main', - [ ] - ); + /** + * @NoAdminRequired + * @NoCSRFRequired + * + * @return TemplateResponse + */ + public function index() { + $response = new TemplateResponse( + $this->appName, + 'main', + [ ] + ); - $csp = new ContentSecurityPolicy(); - $csp->addAllowedImageDomain('*'); - $response->setContentSecurityPolicy($csp); - - return $response; - } + $csp = new ContentSecurityPolicy(); + $csp->addAllowedImageDomain('*'); + $response->setContentSecurityPolicy($csp); + return $response; + } } diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index 8b9f2648..b880d417 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -1,5 +1,6 @@ findEntities($sql, [$userId]); - } - - public function get($userId, $fileId) { - $sql = 'SELECT * FROM `*PREFIX*notes_meta` WHERE user_id=? AND file_id=?'; - return $this->findEntity($sql, [$userId, $fileId]); + $qb = $this->db->getQueryBuilder(); + $qb->select('*') + ->from('*PREFIX*notes_meta') + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + return $this->findEntities($qb); } } diff --git a/lib/Db/Note.php b/lib/Db/Note.php index 284a9bca..8f4afd5c 100644 --- a/lib/Db/Note.php +++ b/lib/Db/Note.php @@ -1,20 +1,11 @@ - * @copyright Bernhard Posselt 2012, 2014 - */ namespace OCA\Notes\Db; use OCP\Files\File; use OCP\Files\Folder; use OCP\AppFramework\Db\Entity; -use League\Flysystem\FileNotFoundException; + /** * Class Note * @method integer getId() @@ -38,87 +29,88 @@ use League\Flysystem\FileNotFoundException; * @package OCA\Notes\Db */ class Note extends Entity { - public $etag; - public $modified; - public $title; - public $category; - public $content = null; - public $favorite = false; - public $error = false; - public $errorMessage=''; + public $etag; + public $modified; + public $title; + public $category; + public $content = null; + public $favorite = false; + public $error = false; + public $errorMessage=''; - public function __construct() { - $this->addType('modified', 'integer'); - $this->addType('favorite', 'boolean'); - } + public function __construct() { + $this->addType('modified', 'integer'); + $this->addType('favorite', 'boolean'); + } - /** - * @param File $file - * @return static - */ - public static function fromFile(File $file, Folder $notesFolder, $tags=[], $onlyMeta=false) { - $note = new static(); - $note->setId($file->getId()); - if(!$onlyMeta) { - $fileContent=$file->getContent(); - if($fileContent===false){ - throw new FileNotFoundException("File not found"); - } - $note->setContent(self::convertEncoding($fileContent)); - } - $note->setModified($file->getMTime()); - $note->setTitle(pathinfo($file->getName(),PATHINFO_FILENAME)); // remove extension - $subdir = substr(dirname($file->getPath()), strlen($notesFolder->getPath())+1); - $note->setCategory($subdir ? $subdir : ''); - if(is_array($tags) && in_array(\OC\Tags::TAG_FAVORITE, $tags)) { - $note->setFavorite(true); - //unset($tags[array_search(\OC\Tags::TAG_FAVORITE, $tags)]); - } - if(!$onlyMeta) { - $note->updateETag(); - } - $note->resetUpdatedFields(); - return $note; - } - /** - * @param File $file - * @return static - */ - public static function fromException($message,File $file,Folder $notesFolder,$tags=[]){ - $note = new static(); - $note->setId($file->getId()); - $note->setErrorMessage($message); - $note->setError(true); - $note->setContent($message); - $note->setModified(null); - $note->setTitle(pathinfo($file->getName(),PATHINFO_FILENAME)); // remove extension - $subdir = substr(dirname($file->getPath()), strlen($notesFolder->getPath())+1); - $note->setCategory($subdir ? $subdir : null); - if(is_array($tags) && in_array(\OC\Tags::TAG_FAVORITE, $tags)) { - $note->setFavorite(true); - //unset($tags[array_search(\OC\Tags::TAG_FAVORITE, $tags)]); - } - $note->updateETag(); - $note->resetUpdatedFields(); - return $note; - } + /** + * @param File $file + * @return static + */ + public static function fromFile(File $file, Folder $notesFolder, $tags = [], $onlyMeta = false) { + $note = new static(); + $note->setId($file->getId()); + if (!$onlyMeta) { + $fileContent=$file->getContent(); + if ($fileContent===false) { + throw new \Exception("File not found"); + } + $note->setContent(self::convertEncoding($fileContent)); + } + $note->setModified($file->getMTime()); + $note->setTitle(pathinfo($file->getName(), PATHINFO_FILENAME)); // remove extension + $subdir = substr(dirname($file->getPath()), strlen($notesFolder->getPath())+1); + $note->setCategory($subdir ? $subdir : ''); + if (is_array($tags) && in_array(\OC\Tags::TAG_FAVORITE, $tags)) { + $note->setFavorite(true); + //unset($tags[array_search(\OC\Tags::TAG_FAVORITE, $tags)]); + } + if (!$onlyMeta) { + $note->updateETag(); + } + $note->resetUpdatedFields(); + return $note; + } - private static function convertEncoding($str) { - if(!mb_check_encoding($str, 'UTF-8')) { - $str = mb_convert_encoding($str, 'UTF-8'); - } - return $str; - } + /** + * @param File $file + * @return static + */ + public static function fromException($message, File $file, Folder $notesFolder, $tags = []) { + $note = new static(); + $note->setId($file->getId()); + $note->setErrorMessage($message); + $note->setError(true); + $note->setContent($message); + $note->setModified(null); + $note->setTitle(pathinfo($file->getName(), PATHINFO_FILENAME)); // remove extension + $subdir = substr(dirname($file->getPath()), strlen($notesFolder->getPath())+1); + $note->setCategory($subdir ? $subdir : null); + if (is_array($tags) && in_array(\OC\Tags::TAG_FAVORITE, $tags)) { + $note->setFavorite(true); + //unset($tags[array_search(\OC\Tags::TAG_FAVORITE, $tags)]); + } + $note->updateETag(); + $note->resetUpdatedFields(); + return $note; + } - private function updateETag() { - // collect all relevant attributes - $data = ''; - foreach(get_object_vars($this) as $key => $val) { - if($key!=='etag') { - $data .= $val; - } - } - $etag = md5($data); - $this->setEtag($etag); - } + private static function convertEncoding($str) { + if (!mb_check_encoding($str, 'UTF-8')) { + $str = mb_convert_encoding($str, 'UTF-8'); + } + return $str; + } + + private function updateETag() { + // collect all relevant attributes + $data = ''; + foreach (get_object_vars($this) as $key => $val) { + if ($key!=='etag') { + $data .= $val; + } + } + $etag = md5($data); + $this->setEtag($etag); + } } diff --git a/lib/Service/MetaService.php b/lib/Service/MetaService.php index a3a403aa..994add64 100644 --- a/lib/Service/MetaService.php +++ b/lib/Service/MetaService.php @@ -1,10 +1,4 @@ metaMapper->getAll($userId); $metas = $this->getIndexedArray($metas, 'fileId'); $notes = $this->getIndexedArray($notes, 'id'); - foreach($metas as $id=>$meta) { - if(!array_key_exists($id, $notes)) { + foreach ($metas as $id => $meta) { + if (!array_key_exists($id, $notes)) { // DELETE obsolete notes $this->metaMapper->delete($meta); unset($metas[$id]); } } - foreach($notes as $id=>$note) { - if(!array_key_exists($id, $metas)) { + foreach ($notes as $id => $note) { + if (!array_key_exists($id, $metas)) { // INSERT new notes $metas[$note->getId()] = $this->create($userId, $note); - } elseif($note->getEtag()!==$metas[$id]->getEtag()) { + } elseif ($note->getEtag()!==$metas[$id]->getEtag()) { // UPDATE changed notes $meta = $metas[$id]; $this->updateIfNeeded($meta, $note); @@ -53,7 +47,7 @@ class MetaService { $property = ucfirst($property); $getter = 'get'.$property; $result = array(); - foreach($data as $entity) { + foreach ($data as $entity) { $result[$entity->$getter()] = $entity; } return $result; @@ -66,7 +60,7 @@ class MetaService { } private function updateIfNeeded(&$meta, $note) { - if($note->getEtag()!==$meta->getEtag()) { + if ($note->getEtag()!==$meta->getEtag()) { $meta->setEtag($note->getEtag()); $meta->setLastUpdate(time()); $this->metaMapper->update($meta); diff --git a/lib/Service/NoteDoesNotExistException.php b/lib/Service/NoteDoesNotExistException.php index 95004402..fc904e5a 100644 --- a/lib/Service/NoteDoesNotExistException.php +++ b/lib/Service/NoteDoesNotExistException.php @@ -1,13 +1,4 @@ - * @copyright Bernhard Posselt 2012, 2014 - */ namespace OCA\Notes\Service; @@ -18,4 +9,5 @@ use Exception; * * @package OCA\Notes\Service */ -class NoteDoesNotExistException extends Exception {} \ No newline at end of file +class NoteDoesNotExistException extends Exception { +} diff --git a/lib/Service/NotesFolderException.php b/lib/Service/NotesFolderException.php index e39871fa..8b98f3de 100644 --- a/lib/Service/NotesFolderException.php +++ b/lib/Service/NotesFolderException.php @@ -1,11 +1,4 @@ - * @copyright Bernhard Posselt 2012, 2014 - */ namespace OCA\Notes\Service; @@ -17,13 +8,11 @@ use OCP\Files\IRootFolder; use OCP\Files\Folder; use OCP\ILogger; use OCP\Encryption\Exceptions\GenericEncryptionException; -use League\Flysystem\FileNotFoundException; use OCA\Notes\Db\Note; use OCA\Notes\Service\SettingsService; use OCP\IConfig; use OCP\IUserSession; - /** * Class NotesService * @@ -31,12 +20,12 @@ use OCP\IUserSession; */ class NotesService { - private $l10n; - private $root; - private $logger; - private $config; - private $settings; - private $appName; + private $l10n; + private $root; + private $logger; + private $config; + private $settings; + private $appName; /** * @param IRootFolder $root @@ -46,374 +35,379 @@ class NotesService { * @param \OCA\Notes\Service\SettingsService $settings * @param String $appName */ - public function __construct (IRootFolder $root, IL10N $l10n, ILogger $logger, IConfig $config, SettingsService $settings, $appName) { - $this->root = $root; - $this->l10n = $l10n; - $this->logger = $logger; - $this->config = $config; - $this->settings = $settings; - $this->appName = $appName; - } + public function __construct(IRootFolder $root, IL10N $l10n, ILogger $logger, IConfig $config, SettingsService $settings, $appName) { + $this->root = $root; + $this->l10n = $l10n; + $this->logger = $logger; + $this->config = $config; + $this->settings = $settings; + $this->appName = $appName; + } - /** - * @param string $userId - * @return array with all notes in the current directory - */ - public function getAll ($userId, $onlyMeta=false) { - $notesFolder = $this->getFolderForUser($userId); - $notes = $this->gatherNoteFiles($notesFolder); - $filesById = []; - foreach($notes as $note) { - $filesById[$note->getId()] = $note; - } - $tagger = \OC::$server->getTagManager()->load('files'); - if($tagger===null) { - $tags = []; - } else { - $tags = $tagger->getTagsForObjects(array_keys($filesById)); - } + /** + * @param string $userId + * @return array with all notes in the current directory + */ + public function getAll($userId, $onlyMeta = false) { + $notesFolder = $this->getFolderForUser($userId); + $notes = $this->gatherNoteFiles($notesFolder); + $filesById = []; + foreach ($notes as $note) { + $filesById[$note->getId()] = $note; + } + $tagger = \OC::$server->getTagManager()->load('files'); + if ($tagger===null) { + $tags = []; + } else { + $tags = $tagger->getTagsForObjects(array_keys($filesById)); + } - $notes = []; - foreach($filesById as $id=>$file) { - $notes[] = $this->getNote($file, $notesFolder, array_key_exists($id, $tags) ? $tags[$id] : [], $onlyMeta); - } + $notes = []; + foreach ($filesById as $id => $file) { + $notes[] = $this->getNote($file, $notesFolder, array_key_exists($id, $tags) ? $tags[$id] : [], $onlyMeta); + } - return $notes; - } + return $notes; + } - /** - * Used to get a single note by id - * @param int $id the id of the note to get - * @param string $userId - * @throws NoteDoesNotExistException if note does not exist - * @return Note - */ - public function get ($id, $userId) { - $folder = $this->getFolderForUser($userId); - return $this->getNote($this->getFileById($folder, $id), $folder, $this->getTags($id)); - } + /** + * Used to get a single note by id + * @param int $id the id of the note to get + * @param string $userId + * @throws NoteDoesNotExistException if note does not exist + * @return Note + */ + public function get($id, $userId) { + $folder = $this->getFolderForUser($userId); + return $this->getNote($this->getFileById($folder, $id), $folder, $this->getTags($id)); + } - private function getTags ($id) { - $tagger = \OC::$server->getTagManager()->load('files'); - if($tagger===null) { - $tags = []; - } else { - $tags = $tagger->getTagsForObjects([$id]); - } - return array_key_exists($id, $tags) ? $tags[$id] : []; - } + private function getTags($id) { + $tagger = \OC::$server->getTagManager()->load('files'); + if ($tagger===null) { + $tags = []; + } else { + $tags = $tagger->getTagsForObjects([$id]); + } + return array_key_exists($id, $tags) ? $tags[$id] : []; + } - private function getNote($file, $notesFolder, $tags=[], $onlyMeta=false) { - $id = $file->getId(); - try { - $note = Note::fromFile($file, $notesFolder, $tags, $onlyMeta); - } catch(FileNotFoundException $e){ - $note = Note::fromException($this->l10n->t('File error').': ('.$file->getName().') '.$e->getMessage(), $file, $notesFolder, array_key_exists($id, $tags) ? $tags[$id] : []); - } catch(GenericEncryptionException $e) { - $note = Note::fromException($this->l10n->t('Encryption Error').': ('.$file->getName().') '.$e->getMessage(), $file, $notesFolder, array_key_exists($id, $tags) ? $tags[$id] : []); - } catch(\Exception $e) { - $note = Note::fromException($this->l10n->t('Error').': ('.$file->getName().') '.$e->getMessage(), $file, $notesFolder, array_key_exists($id, $tags) ? $tags[$id] : []); - } - return $note; - } + private function getNote($file, $notesFolder, $tags = [], $onlyMeta = false) { + $id = $file->getId(); + try { + $note = Note::fromFile($file, $notesFolder, $tags, $onlyMeta); + } catch (GenericEncryptionException $e) { + $note = Note::fromException($this->l10n->t('Encryption Error').': ('.$file->getName().') '.$e->getMessage(), $file, $notesFolder, array_key_exists($id, $tags) ? $tags[$id] : []); + } catch (\Exception $e) { + $note = Note::fromException($this->l10n->t('Error').': ('.$file->getName().') '.$e->getMessage(), $file, $notesFolder, array_key_exists($id, $tags) ? $tags[$id] : []); + } + return $note; + } - /** - * Creates a note and returns the empty note - * @param string $userId - * @see update for setting note content - * @return Note the newly created note - */ - public function create ($userId) { - $title = $this->l10n->t('New note'); - $folder = $this->getFolderForUser($userId); + /** + * Creates a note and returns the empty note + * @param string $userId + * @see update for setting note content + * @return Note the newly created note + */ + public function create($userId) { + $title = $this->l10n->t('New note'); + $folder = $this->getFolderForUser($userId); - // check new note exists already and we need to number it - // pass -1 because no file has id -1 and that will ensure - // to only return filenames that dont yet exist - $path = $this->generateFileName($folder, $title, $this->settings->get($userId, 'fileSuffix'), -1); - $file = $folder->newFile($path); + // check new note exists already and we need to number it + // pass -1 because no file has id -1 and that will ensure + // to only return filenames that dont yet exist + $path = $this->generateFileName($folder, $title, $this->settings->get($userId, 'fileSuffix'), -1); + $file = $folder->newFile($path); - // If server-side encryption is activated, the server creates an empty file without signature - // which leads to an GenericEncryptionException('Missing Signature') afterwards. - // Saving a space-char (and removing it later) is a working work-around. - $file->putContent(' '); + // If server-side encryption is activated, the server creates an empty file without signature + // which leads to an GenericEncryptionException('Missing Signature') afterwards. + // Saving a space-char (and removing it later) is a working work-around. + $file->putContent(' '); - return $this->getNote($file, $folder); - } + return $this->getNote($file, $folder); + } - /** - * Updates a note. Be sure to check the returned note since the title is - * dynamically generated and filename conflicts are resolved - * @param int $id the id of the note used to update - * @param string $content the content which will be written into the note - * the title is generated from the first line of the content - * @param int $mtime time of the note modification (optional) - * @throws NoteDoesNotExistException if note does not exist - * @return \OCA\Notes\Db\Note the updated note - */ - public function update ($id, $content, $userId, $category=null, $mtime=0) { - $notesFolder = $this->getFolderForUser($userId); - $file = $this->getFileById($notesFolder, $id); - $title = $this->getSafeTitleFromContent( $content===null ? $file->getContent() : $content ); + /** + * Updates a note. Be sure to check the returned note since the title is + * dynamically generated and filename conflicts are resolved + * @param int $id the id of the note used to update + * @param string|null $content the content which will be written into the note + * the title is generated from the first line of the content + * @param string|null $category the category in which the note should be saved + * @param int $mtime time of the note modification (optional) + * @throws NoteDoesNotExistException if note does not exist + * @return \OCA\Notes\Db\Note the updated note + */ + public function update($id, $content, $userId, $category = null, $mtime = 0) { + $notesFolder = $this->getFolderForUser($userId); + $file = $this->getFileById($notesFolder, $id); + $title = $this->getSafeTitleFromContent($content===null ? $file->getContent() : $content); - // rename/move file with respect to title/category - // this can fail if access rights are not sufficient or category name is illegal - try { - $currentFilePath = $this->root->getFullPath($file->getPath()); - $currentBasePath = pathinfo($currentFilePath, PATHINFO_DIRNAME); - $fileSuffix = '.' . pathinfo($file->getName(), PATHINFO_EXTENSION); + // rename/move file with respect to title/category + // this can fail if access rights are not sufficient or category name is illegal + try { + $currentFilePath = $this->root->getFullPath($file->getPath()); + $currentBasePath = pathinfo($currentFilePath, PATHINFO_DIRNAME); + $fileSuffix = '.' . pathinfo($file->getName(), PATHINFO_EXTENSION); - // detect (new) folder path based on category name - if($category===null) { - $basePath = $currentBasePath; - } else { - $basePath = $notesFolder->getPath(); - if(!empty($category)) { - // sanitise path - $cats = explode('/', $category); - $cats = array_map([$this, 'sanitisePath'], $cats); - $cats = array_filter($cats, function($str) { return !empty($str); }); - $basePath .= '/'.implode('/', $cats); - } - } - $folder = $this->getOrCreateFolder($basePath); + // detect (new) folder path based on category name + if ($category===null) { + $basePath = $currentBasePath; + } else { + $basePath = $notesFolder->getPath(); + if (!empty($category)) { + // sanitise path + $cats = explode('/', $category); + $cats = array_map([$this, 'sanitisePath'], $cats); + $cats = array_filter($cats, function ($str) { + return !empty($str); + }); + $basePath .= '/'.implode('/', $cats); + } + } + $folder = $this->getOrCreateFolder($basePath); - // assemble new file path - $newFilePath = $basePath . '/' . $this->generateFileName($folder, $title, $fileSuffix, $id); + // assemble new file path + $newFilePath = $basePath . '/' . $this->generateFileName($folder, $title, $fileSuffix, $id); - // if the current path is not the new path, the file has to be renamed - if($currentFilePath !== $newFilePath) { - $file->move($newFilePath); - } - if($currentBasePath !== $basePath) { - $this->deleteEmptyFolder($notesFolder, $this->root->get($currentBasePath)); - } - } catch(\OCP\Files\NotPermittedException $e) { - $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]); - } catch(\Exception $e) { - $this->logger->error('Moving note '.$id.' ('.$title.') to the desired target has failed with a '.get_class($e).': '.$e->getMessage(), ['app' => $this->appName]); - } + // if the current path is not the new path, the file has to be renamed + if ($currentFilePath !== $newFilePath) { + $file->move($newFilePath); + } + if ($currentBasePath !== $basePath) { + $this->deleteEmptyFolder($notesFolder, $this->root->get($currentBasePath)); + } + } catch (\OCP\Files\NotPermittedException $e) { + $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]); + } catch (\Exception $e) { + $this->logger->error('Moving note '.$id.' ('.$title.') to the desired target has failed with a '.get_class($e).': '.$e->getMessage(), ['app' => $this->appName]); + } - if($content !== null) { - $file->putContent($content); - } + if ($content !== null) { + $file->putContent($content); + } - if($mtime) { - $file->touch($mtime); - } + if ($mtime) { + $file->touch($mtime); + } - return $this->getNote($file, $notesFolder, $this->getTags($id)); - } + return $this->getNote($file, $notesFolder, $this->getTags($id)); + } - /** - * Set or unset a note as favorite. - * @param int $id the id of the note used to update - * @param boolean $favorite whether the note should be a favorite or not - * @throws NoteDoesNotExistException if note does not exist - * @return boolean the new favorite state of the note - */ - public function favorite ($id, $favorite, $userId){ - $folder = $this->getFolderForUser($userId); - $file = $this->getFileById($folder, $id); - if(!$this->isNote($file)) { - throw new NoteDoesNotExistException(); - } - $tagger = \OC::$server->getTagManager()->load('files'); - if($favorite) - $tagger->addToFavorites($id); - else - $tagger->removeFromFavorites($id); + /** + * Set or unset a note as favorite. + * @param int $id the id of the note used to update + * @param boolean $favorite whether the note should be a favorite or not + * @throws NoteDoesNotExistException if note does not exist + * @return boolean the new favorite state of the note + */ + public function favorite($id, $favorite, $userId) { + $folder = $this->getFolderForUser($userId); + $file = $this->getFileById($folder, $id); + if (!$this->isNote($file)) { + throw new NoteDoesNotExistException(); + } + $tagger = \OC::$server->getTagManager()->load('files'); + if ($favorite) { + $tagger->addToFavorites($id); + } else { + $tagger->removeFromFavorites($id); + } - $tags = $tagger->getTagsForObjects([$id]); - return array_key_exists($id, $tags) && in_array(\OC\Tags::TAG_FAVORITE, $tags[$id]); - } + $tags = $tagger->getTagsForObjects([$id]); + return array_key_exists($id, $tags) && in_array(\OC\Tags::TAG_FAVORITE, $tags[$id]); + } - /** - * Deletes a note - * @param int $id the id of the note which should be deleted - * @param string $userId - * @throws NoteDoesNotExistException if note does not - * exist - */ - public function delete ($id, $userId) { - $notesFolder = $this->getFolderForUser($userId); - $file = $this->getFileById($notesFolder, $id); - $parent = $file->getParent(); - $file->delete(); - $this->deleteEmptyFolder($notesFolder, $parent); - } + /** + * Deletes a note + * @param int $id the id of the note which should be deleted + * @param string $userId + * @throws NoteDoesNotExistException if note does not + * exist + */ + public function delete($id, $userId) { + $notesFolder = $this->getFolderForUser($userId); + $file = $this->getFileById($notesFolder, $id); + $parent = $file->getParent(); + $file->delete(); + $this->deleteEmptyFolder($notesFolder, $parent); + } - // removes characters that are illegal in a file or folder name on some operating systems - private function sanitisePath($str) { - // remove characters which are illegal on Windows (includes illegal characters on Unix/Linux) - // prevents also directory traversal by eliminiating slashes - // see also \OC\Files\Storage\Common::verifyPosixPath(...) - $str = str_replace(['*', '|', '/', '\\', ':', '"', '<', '>', '?'], '', $str); + // removes characters that are illegal in a file or folder name on some operating systems + private function sanitisePath($str) { + // remove characters which are illegal on Windows (includes illegal characters on Unix/Linux) + // prevents also directory traversal by eliminiating slashes + // see also \OC\Files\Storage\Common::verifyPosixPath(...) + $str = str_replace(['*', '|', '/', '\\', ':', '"', '<', '>', '?'], '', $str); - // if mysql doesn't support 4byte UTF-8, then remove those characters - // see \OC\Files\Storage\Common::verifyPath(...) - if (!\OC::$server->getDatabaseConnection()->supports4ByteText()) { - $str = preg_replace('%(?: + // if mysql doesn't support 4byte UTF-8, then remove those characters + // see \OC\Files\Storage\Common::verifyPath(...) + if (!\OC::$server->getDatabaseConnection()->supports4ByteText()) { + $str = preg_replace('%(?: \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 )%xs', '', $str); - } + } - // prevent file to be hidden - $str = preg_replace("/^[\. ]+/mu", "", $str); - return trim($str); - } + // prevent file to be hidden + $str = preg_replace("/^[\. ]+/mu", "", $str); + return trim($str); + } - private function getSafeTitleFromContent($content) { - // prepare content: remove markdown characters and empty spaces - $content = preg_replace("/^\s*[*+-]\s+/mu", "", $content); // list item - $content = preg_replace("/^#+\s+(.*?)\s*#*$/mu", "$1", $content); // headline - $content = preg_replace("/^(=+|-+)$/mu", "", $content); // separate line for headline - $content = preg_replace("/(\*+|_+)(.*?)\\1/mu", "$2", $content); // emphasis + private function getSafeTitleFromContent($content) { + // prepare content: remove markdown characters and empty spaces + $content = preg_replace("/^\s*[*+-]\s+/mu", "", $content); // list item + $content = preg_replace("/^#+\s+(.*?)\s*#*$/mu", "$1", $content); // headline + $content = preg_replace("/^(=+|-+)$/mu", "", $content); // separate line for headline + $content = preg_replace("/(\*+|_+)(.*?)\\1/mu", "$2", $content); // emphasis - // sanitize: prevent directory traversal, illegal characters and unintended file names - $content = $this->sanitisePath($content); + // sanitize: prevent directory traversal, illegal characters and unintended file names + $content = $this->sanitisePath($content); - // generate title from the first line of the content - $splitContent = preg_split("/\R/u", $content, 2); - $title = trim($splitContent[0]); + // generate title from the first line of the content + $splitContent = preg_split("/\R/u", $content, 2); + $title = trim($splitContent[0]); - // ensure that title is not empty - if(empty($title)) { - $title = $this->l10n->t('New note'); - } + // ensure that title is not empty + if (empty($title)) { + $title = $this->l10n->t('New note'); + } - // using a maximum of 100 chars should be enough - $title = mb_substr($title, 0, 100, "UTF-8"); + // using a maximum of 100 chars should be enough + $title = mb_substr($title, 0, 100, "UTF-8"); - return $title; - } + return $title; + } - /** - * @param Folder $folder - * @param int $id - * @throws NoteDoesNotExistException - * @return \OCP\Files\File - */ - private function getFileById ($folder, $id) { - $file = $folder->getById($id); + /** + * @param Folder $folder + * @param int $id + * @throws NoteDoesNotExistException + * @return \OCP\Files\File + */ + private function getFileById($folder, $id) { + $file = $folder->getById($id); - if(count($file) <= 0 || !$this->isNote($file[0])) { - throw new NoteDoesNotExistException(); - } - return $file[0]; - } + if (count($file) <= 0 || !$this->isNote($file[0])) { + throw new NoteDoesNotExistException(); + } + return $file[0]; + } - /** - * @param string $userId the user id - * @return boolean true if folder is accessible, or Exception otherwise - */ - public function checkNotesFolder($userId) { - $folder = $this->getFolderForUser($userId); - return true; - } + /** + * @param string $userId the user id + * @return boolean true if folder is accessible, or Exception otherwise + */ + public function checkNotesFolder($userId) { + $this->getFolderForUser($userId); + return true; + } - /** - * @param string $userId the user id - * @return Folder - */ - private function getFolderForUser ($userId) { - $path = '/' . $userId . '/files/' . $this->settings->get($userId, 'notesPath'); - try { - $folder = $this->getOrCreateFolder($path); - } catch(\Exception $e) { - throw new NotesFolderException($path); - } - return $folder; - } + /** + * @param string $userId the user id + * @return Folder + */ + private function getFolderForUser($userId) { + $path = '/' . $userId . '/files/' . $this->settings->get($userId, 'notesPath'); + try { + $folder = $this->getOrCreateFolder($path); + } catch (\Exception $e) { + throw new NotesFolderException($path); + } + return $folder; + } - /** - * Finds a folder and creates it if non-existent - * @param string $path path to the folder - * @return Folder - */ - private function getOrCreateFolder($path) { - if ($this->root->nodeExists($path)) { - $folder = $this->root->get($path); - } else { - $folder = $this->root->newFolder($path); - } - return $folder; - } + /** + * Finds a folder and creates it if non-existent + * @param string $path path to the folder + * @return Folder + */ + private function getOrCreateFolder($path) { + if ($this->root->nodeExists($path)) { + $folder = $this->root->get($path); + } else { + $folder = $this->root->newFolder($path); + } + return $folder; + } - /* - * Delete a folder and it's parent(s) if it's/they're empty - * @param Folder root folder for notes - * @param Folder folder to delete - */ - private function deleteEmptyFolder(Folder $notesFolder, Folder $folder) { - $content = $folder->getDirectoryListing(); - $isEmpty = !count($content); - $isNotesFolder = $folder->getPath()===$notesFolder->getPath(); - if($isEmpty && !$isNotesFolder) { - $this->logger->info('Deleting empty category folder '.$folder->getPath(), ['app' => $this->appName]); - $parent = $folder->getParent(); - $folder->delete(); - $this->deleteEmptyFolder($notesFolder, $parent); - } - } + /* + * Delete a folder and it's parent(s) if it's/they're empty + * @param Folder root folder for notes + * @param Folder folder to delete + */ + private function deleteEmptyFolder(Folder $notesFolder, Folder $folder) { + $content = $folder->getDirectoryListing(); + $isEmpty = !count($content); + $isNotesFolder = $folder->getPath()===$notesFolder->getPath(); + if ($isEmpty && !$isNotesFolder) { + $this->logger->info('Deleting empty category folder '.$folder->getPath(), ['app' => $this->appName]); + $parent = $folder->getParent(); + $folder->delete(); + $this->deleteEmptyFolder($notesFolder, $parent); + } + } - /** - * get path of file and the title.txt and check if they are the same - * file. If not the title needs to be renamed - * - * @param Folder $folder a folder to the notes directory - * @param string $title the filename which should be used - * @param string $suffix the suffix (incl. dot) which should be used - * @param int $id the id of the note for which the title should be generated - * used to see if the file itself has the title and not a different file for - * checking for filename collisions - * @return string the resolved filename to prevent overwriting different - * files with the same title - */ - private function generateFileName (Folder $folder, $title, $suffix, $id) { - $path = $title . $suffix; + /** + * get path of file and the title.txt and check if they are the same + * file. If not the title needs to be renamed + * + * @param Folder $folder a folder to the notes directory + * @param string $title the filename which should be used + * @param string $suffix the suffix (incl. dot) which should be used + * @param int $id the id of the note for which the title should be generated + * used to see if the file itself has the title and not a different file for + * checking for filename collisions + * @return string the resolved filename to prevent overwriting different + * files with the same title + */ + private function generateFileName(Folder $folder, $title, $suffix, $id) { + $path = $title . $suffix; - // if file does not exist, that name has not been taken. Similar we don't - // need to handle file collisions if it is the filename did not change - if (!$folder->nodeExists($path) || $folder->get($path)->getId() === $id) { - return $path; - } else { - // increments name (2) to name (3) - $match = preg_match('/\((?P\d+)\)$/u', $title, $matches); - if($match) { - $newId = ((int) $matches['id']) + 1; - $newTitle = preg_replace('/(.*)\s\((\d+)\)$/u', - '$1 (' . $newId . ')', $title); - } else { - $newTitle = $title . ' (2)'; - } - return $this->generateFileName($folder, $newTitle, $suffix, $id); - } - } + // if file does not exist, that name has not been taken. Similar we don't + // need to handle file collisions if it is the filename did not change + if (!$folder->nodeExists($path) || $folder->get($path)->getId() === $id) { + return $path; + } else { + // increments name (2) to name (3) + $match = preg_match('/\((?P\d+)\)$/u', $title, $matches); + if ($match) { + $newId = ((int) $matches['id']) + 1; + $newTitle = preg_replace( + '/(.*)\s\((\d+)\)$/u', + '$1 (' . $newId . ')', + $title + ); + } else { + $newTitle = $title . ' (2)'; + } + return $this->generateFileName($folder, $newTitle, $suffix, $id); + } + } /** * gather note files in given directory and all subdirectories * @param Folder $folder * @return array */ - private function gatherNoteFiles ($folder) { + private function gatherNoteFiles($folder) { $notes = []; $nodes = $folder->getDirectoryListing(); - foreach($nodes as $node) { - if($node->getType() === FileInfo::TYPE_FOLDER) { + foreach ($nodes as $node) { + if ($node->getType() === FileInfo::TYPE_FOLDER) { $notes = array_merge($notes, $this->gatherNoteFiles($node)); continue; } - if($this->isNote($node)) { + if ($this->isNote($node)) { $notes[] = $node; } } @@ -421,23 +415,24 @@ class NotesService { } - /** - * test if file is a note - * - * @param \OCP\Files\File $file - * @return bool - */ - private function isNote($file) { - $allowedExtensions = ['txt', 'org', 'markdown', 'md', 'note']; + /** + * test if file is a note + * + * @param \OCP\Files\File $file + * @return bool + */ + private function isNote($file) { + $allowedExtensions = ['txt', 'org', 'markdown', 'md', 'note']; - if($file->getType() !== 'file') return false; - - $ext = pathinfo($file->getName(), PATHINFO_EXTENSION); - $iext = strtolower($ext); - if(!in_array($iext, $allowedExtensions)) { - return false; - } - return true; - } + if ($file->getType() !== 'file') { + return false; + } + $ext = pathinfo($file->getName(), PATHINFO_EXTENSION); + $iext = strtolower($ext); + if (!in_array($iext, $allowedExtensions)) { + return false; + } + return true; + } } diff --git a/lib/Service/SettingsService.php b/lib/Service/SettingsService.php index 90cc2e18..51f30b67 100644 --- a/lib/Service/SettingsService.php +++ b/lib/Service/SettingsService.php @@ -1,6 +1,7 @@ "Notes", - "fileSuffix" => ".txt", + 'notesPath' => 'Notes', + 'fileSuffix' => '.txt', ]; public function __construct( @@ -32,8 +33,8 @@ class SettingsService */ public function set($uid, $settings) { // remove illegal, empty and default settings - foreach($settings as $name => $value) { - if(!array_key_exists($name, $this->defaults) + foreach ($settings as $name => $value) { + if (!array_key_exists($name, $this->defaults) || empty($value) || $value === $this->defaults[$name] ) { @@ -45,10 +46,10 @@ class SettingsService public function getAll($uid) { $settings = json_decode($this->config->getUserValue($uid, 'notes', 'settings')); - if(is_object($settings)) { + if (is_object($settings)) { // use default for empty settings - foreach($this->defaults as $name => $defaultValue) { - if(!property_exists($settings, $name) || empty($settings->{$name})) { + foreach ($this->defaults as $name => $defaultValue) { + if (!property_exists($settings, $name) || empty($settings->{$name})) { $settings->{$name} = $defaultValue; } } @@ -63,7 +64,7 @@ class SettingsService */ public function get($uid, $name) { $settings = $this->getAll($uid); - if(property_exists($settings, $name)) { + if (property_exists($settings, $name)) { return $settings->{$name}; } else { throw new \OCP\PreConditionNotMetException('Setting '.$name.' not found for user '.$uid.'.'); diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 00000000..492cf92a --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,32 @@ + + + + PSR2 with changes: + * tabs instead of spaces (https://gist.github.com/gsherwood/9d22f634c57f990a7c64) + * bracers on end of line instead new line + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file