From fe2e6bb2e5430e8fb1b6d53a6b5be3bc9e27949d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Sat, 14 Sep 2024 19:52:43 +0200 Subject: [PATCH 01/10] chore: Add vendor-bin and csfixer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- composer.json | 10 ++- composer.lock | 61 ++++++++++++++++- vendor-bin/csfixer/composer.json | 5 ++ vendor-bin/csfixer/composer.lock | 112 +++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 vendor-bin/csfixer/composer.json create mode 100644 vendor-bin/csfixer/composer.lock diff --git a/composer.json b/composer.json index f0dc1de54..f5a8305d2 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,8 @@ "bogdaan/open-location-code": "dev-master" }, "require-dev": { - "christophwurst/nextcloud_testing": "^0.12.4" + "christophwurst/nextcloud_testing": "^0.12.4", + "bamarni/composer-bin-plugin": "*" }, "scripts": { "test:integration": "phpunit -c tests/phpunit.integration.xml --fail-on-warning", @@ -16,5 +17,10 @@ "files": [ "lib/Helper/functions.php" ] - } + }, + "config": { + "allow-plugins": { + "bamarni/composer-bin-plugin": true + } + } } diff --git a/composer.lock b/composer.lock index 454684484..81830164c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5c8c7ae13a82b591c4292373492fd0d2", + "content-hash": "1ca1bda1e8aa6c8e16b7661db5e5d085", "packages": [ { "name": "bogdaan/open-location-code", @@ -119,6 +119,63 @@ } ], "packages-dev": [ + { + "name": "bamarni/composer-bin-plugin", + "version": "1.8.2", + "source": { + "type": "git", + "url": "https://github.com/bamarni/composer-bin-plugin.git", + "reference": "92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bamarni/composer-bin-plugin/zipball/92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880", + "reference": "92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "composer/composer": "^2.0", + "ext-json": "*", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.5", + "symfony/console": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", + "symfony/finder": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", + "symfony/process": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Bamarni\\Composer\\Bin\\BamarniBinPlugin" + }, + "autoload": { + "psr-4": { + "Bamarni\\Composer\\Bin\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "No conflicts for your bin dependencies", + "keywords": [ + "composer", + "conflict", + "dependency", + "executable", + "isolation", + "tool" + ], + "support": { + "issues": "https://github.com/bamarni/composer-bin-plugin/issues", + "source": "https://github.com/bamarni/composer-bin-plugin/tree/1.8.2" + }, + "time": "2022-10-31T08:38:03+00:00" + }, { "name": "christophwurst/nextcloud_testing", "version": "v0.12.4", @@ -2114,5 +2171,5 @@ "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/vendor-bin/csfixer/composer.json b/vendor-bin/csfixer/composer.json new file mode 100644 index 000000000..b67bf1232 --- /dev/null +++ b/vendor-bin/csfixer/composer.json @@ -0,0 +1,5 @@ +{ + "require-dev": { + "nextcloud/coding-standard": "^1.2" + } +} diff --git a/vendor-bin/csfixer/composer.lock b/vendor-bin/csfixer/composer.lock new file mode 100644 index 000000000..16ba6bc41 --- /dev/null +++ b/vendor-bin/csfixer/composer.lock @@ -0,0 +1,112 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "70f2afb9bd1323f4225d93d6183f384f", + "packages": [], + "packages-dev": [ + { + "name": "nextcloud/coding-standard", + "version": "v1.2.3", + "source": { + "type": "git", + "url": "https://github.com/nextcloud/coding-standard.git", + "reference": "bc9c53a5306114b60c4363057aff9c2ed10a54da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nextcloud/coding-standard/zipball/bc9c53a5306114b60c4363057aff9c2ed10a54da", + "reference": "bc9c53a5306114b60c4363057aff9c2ed10a54da", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0", + "php-cs-fixer/shim": "^3.17" + }, + "type": "library", + "autoload": { + "psr-4": { + "Nextcloud\\CodingStandard\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christoph Wurst", + "email": "christoph@winzerhof-wurst.at" + } + ], + "description": "Nextcloud coding standards for the php cs fixer", + "support": { + "issues": "https://github.com/nextcloud/coding-standard/issues", + "source": "https://github.com/nextcloud/coding-standard/tree/v1.2.3" + }, + "time": "2024-08-23T14:32:32+00:00" + }, + { + "name": "php-cs-fixer/shim", + "version": "v3.64.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/shim.git", + "reference": "81ccfd24baf3a10810dab1152c403981a790b837" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/shim/zipball/81ccfd24baf3a10810dab1152c403981a790b837", + "reference": "81ccfd24baf3a10810dab1152c403981a790b837", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "replace": { + "friendsofphp/php-cs-fixer": "self.version" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer", + "php-cs-fixer.phar" + ], + "type": "application", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "support": { + "issues": "https://github.com/PHP-CS-Fixer/shim/issues", + "source": "https://github.com/PHP-CS-Fixer/shim/tree/v3.64.0" + }, + "time": "2024-08-30T23:10:11+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.6.0" +} From 6d14460597ad53da7ddbc9984d1a6def31c569d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Sat, 14 Sep 2024 20:14:48 +0200 Subject: [PATCH 02/10] chore: Add php-cs-fixer configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- .php-cs-fixer.dist.php | 18 ++++++++++++++++++ composer.json | 7 ++++++- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 .php-cs-fixer.dist.php diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 000000000..e247c5973 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,18 @@ +getFinder() + ->ignoreVCSIgnored(true) + ->notPath('build') + ->notPath('l10n') + ->notPath('src') + ->notPath('vendor') + ->in(__DIR__); +return $config; diff --git a/composer.json b/composer.json index f5a8305d2..e5ba42059 100644 --- a/composer.json +++ b/composer.json @@ -8,6 +8,8 @@ "bamarni/composer-bin-plugin": "*" }, "scripts": { + "cs:fix": "php-cs-fixer fix", + "cs:check": "php-cs-fixer fix --dry-run --diff", "test:integration": "phpunit -c tests/phpunit.integration.xml --fail-on-warning", "test:integration:dev": "phpunit -c tests/phpunit.integration.xml --no-coverage --order-by=defects --stop-on-defect --fail-on-warning --stop-on-error --stop-on-failure", "test:unit": "phpunit -c tests/phpunit.unit.xml --fail-on-warning", @@ -16,7 +18,10 @@ "autoload": { "files": [ "lib/Helper/functions.php" - ] + ], + "psr-4": { + "OCA\\Maps\\": "./lib/" + } }, "config": { "allow-plugins": { From 749fa2d058312611f677d389e6a85e759f014a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Sat, 14 Sep 2024 20:20:52 +0200 Subject: [PATCH 03/10] chore: add workflows for PHP and csfixer lint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- .github/workflows/lint-info-xml.yml | 33 ++++++++++++++ .github/workflows/lint-php-cs.yml | 45 +++++++++++++++++++ .github/workflows/lint-php.yml | 67 +++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 .github/workflows/lint-info-xml.yml create mode 100644 .github/workflows/lint-php-cs.yml create mode 100644 .github/workflows/lint-php.yml diff --git a/.github/workflows/lint-info-xml.yml b/.github/workflows/lint-info-xml.yml new file mode 100644 index 000000000..492e8a01b --- /dev/null +++ b/.github/workflows/lint-info-xml.yml @@ -0,0 +1,33 @@ +# This workflow is provided via the organization template repository +# +# https://github.com/nextcloud/.github +# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization + +name: Lint info.xml + +on: pull_request + +permissions: + contents: read + +concurrency: + group: lint-info-xml-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + xml-linters: + runs-on: ubuntu-latest-low + + name: info.xml lint + steps: + - name: Checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Download schema + run: wget https://raw.githubusercontent.com/nextcloud/appstore/master/nextcloudappstore/api/v1/release/info.xsd + + - name: Lint info.xml + uses: ChristophWurst/xmllint-action@36f2a302f84f8c83fceea0b9c59e1eb4a616d3c1 # v1.2 + with: + xml-file: ./appinfo/info.xml + xml-schema-file: ./info.xsd diff --git a/.github/workflows/lint-php-cs.yml b/.github/workflows/lint-php-cs.yml new file mode 100644 index 000000000..0b3234d05 --- /dev/null +++ b/.github/workflows/lint-php-cs.yml @@ -0,0 +1,45 @@ +# This workflow is provided via the organization template repository +# +# https://github.com/nextcloud/.github +# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization + +name: Lint php-cs + +on: pull_request + +permissions: + contents: read + +concurrency: + group: lint-php-cs-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + lint: + runs-on: ubuntu-latest + + name: php-cs + + steps: + - name: Checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Get php version + id: versions + uses: icewind1991/nextcloud-version-matrix@7d433286e92318f51ed0537b6c77374759e12f46 # v1.3.0 + + - name: Set up php${{ steps.versions.outputs.php-available }} + uses: shivammathur/setup-php@6d7209f44a25a59e904b1ee9f3b0c33ab2cd888d # v2 + with: + php-version: ${{ steps.versions.outputs.php-available }} + extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite + coverage: none + ini-file: development + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install dependencies + run: composer i + + - name: Lint + run: composer run cs:check || ( echo 'Please run `composer run cs:fix` to format your code' && exit 1 ) diff --git a/.github/workflows/lint-php.yml b/.github/workflows/lint-php.yml new file mode 100644 index 000000000..69b9baa28 --- /dev/null +++ b/.github/workflows/lint-php.yml @@ -0,0 +1,67 @@ +# This workflow is provided via the organization template repository +# +# https://github.com/nextcloud/.github +# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization + +name: Lint php + +on: pull_request + +permissions: + contents: read + +concurrency: + group: lint-php-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + matrix: + runs-on: ubuntu-latest-low + outputs: + php-versions: ${{ steps.versions.outputs.php-versions }} + steps: + - name: Checkout app + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - name: Get version matrix + id: versions + uses: icewind1991/nextcloud-version-matrix@111919cfc7b388b7c02cac3c5d53627137adb89f # v1.0.0 + + php-lint: + runs-on: ubuntu-latest + needs: matrix + strategy: + matrix: + php-versions: ${{fromJson(needs.matrix.outputs.php-versions)}} + + name: php-lint + + steps: + - name: Checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Set up php ${{ matrix.php-versions }} + uses: shivammathur/setup-php@6d7209f44a25a59e904b1ee9f3b0c33ab2cd888d # v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite + coverage: none + ini-file: development + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Lint + run: composer run lint + + summary: + permissions: + contents: none + runs-on: ubuntu-latest-low + needs: php-lint + + if: always() + + name: php-lint-summary + + steps: + - name: Summary status + run: if ${{ needs.php-lint.result != 'success' && needs.php-lint.result != 'skipped' }}; then exit 1; fi From b059d12c92bc2dbfa9346ecad1c47cee1a5cb0c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Sat, 14 Sep 2024 20:21:41 +0200 Subject: [PATCH 04/10] chore: composer run cs:fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- appinfo/routes.php | 186 +- lib/AppInfo/Application.php | 38 +- lib/BackgroundJob/AddPhotoJob.php | 62 +- .../LaunchUsersInstallScanJob.php | 52 +- lib/BackgroundJob/LookupMissingGeoJob.php | 64 +- lib/BackgroundJob/UpdatePhotoByFileJob.php | 64 +- lib/BackgroundJob/UserInstallScanJob.php | 106 +- lib/Command/RegisterMimetypes.php | 36 +- lib/Command/RescanPhotos.php | 111 +- lib/Command/RescanTracks.php | 111 +- lib/Controller/ContactsController.php | 409 ++-- lib/Controller/DevicesApiController.php | 261 ++- lib/Controller/DevicesController.php | 437 ++--- lib/Controller/FavoritesApiController.php | 192 +- lib/Controller/FavoritesController.php | 575 +++--- lib/Controller/MyMapsController.php | 81 +- lib/Controller/PageController.php | 192 +- lib/Controller/PhotosController.php | 153 +- lib/Controller/PublicContactsController.php | 62 +- .../PublicFavoritePageController.php | 226 +-- .../PublicFavoritesApiController.php | 338 ++-- lib/Controller/PublicFavoritesController.php | 194 +- lib/Controller/PublicPageController.php | 158 +- lib/Controller/PublicPhotosController.php | 65 +- lib/Controller/PublicTracksController.php | 169 +- lib/Controller/PublicUtilsController.php | 247 ++- lib/Controller/RoutingController.php | 194 +- lib/Controller/TracksController.php | 236 ++- lib/Controller/UtilsController.php | 365 ++-- lib/DB/DeviceShare.php | 12 +- lib/DB/DeviceShareMapper.php | 139 +- lib/DB/FavoriteShare.php | 20 +- lib/DB/FavoriteShareMapper.php | 247 ++- lib/DB/Geophoto.php | 22 +- lib/DB/GeophotoMapper.php | 56 +- lib/Helper/ExifDataInvalidException.php | 3 +- lib/Helper/ExifDataNoLocationException.php | 3 +- lib/Helper/ExifGeoData.php | 679 ++++--- lib/Helper/functions.php | 2 +- lib/Hooks/FileHooks.php | 276 ++- lib/Listener/CardCreatedListener.php | 6 +- lib/Listener/CardDeletedListener.php | 4 +- lib/Listener/CardUpdatedListener.php | 6 +- .../LoadAdditionalScriptsListener.php | 1 - lib/Migration/InstallScan.php | 26 +- lib/Migration/RegisterMimeType.php | 22 +- lib/Migration/UnregisterMimeType.php | 21 +- .../Version000008Date20190428142257.php | 2 +- .../Version000009Date20190625000800.php | 2 +- .../Version000012Date20190703155323.php | 5 +- .../Version000012Date20190722184716.php | 5 +- .../Version000013Date20190723185417.php | 5 +- .../Version000014Date20190817184844.php | 5 +- .../Version000102Date20190901152326.php | 5 +- .../Version000106Date20191118221134.php | 92 +- .../Version000107Date20200608220000.php | 5 +- .../Version000108Date20230310220000.php | 5 +- .../Version100100Date20230731135102.php | 5 +- lib/Service/AddressService.php | 560 +++--- lib/Service/DevicesService.php | 1230 ++++++------ lib/Service/FavoritesService.php | 1625 ++++++++------- lib/Service/GeophotoService.php | 452 +++-- lib/Service/MimetypeService.php | 11 +- lib/Service/MyMapsService.php | 296 ++- lib/Service/PhotofilesService.php | 907 +++++---- lib/Service/TracksService.php | 1743 ++++++++--------- lib/Settings/AdminSettings.php | 120 +- templates/adminSettings.php | 34 +- templates/main.php | 4 +- tests/Integration/AppTest.php | 19 +- .../Db/FavoriteShareMapperTest.php | 131 +- .../Controller/ContactsControllerTest.php | 284 ++- .../Controller/DevicesApiControllerTest.php | 757 ++++--- .../Unit/Controller/DevicesControllerTest.php | 804 ++++---- .../Controller/FavoritesApiControllerTest.php | 465 +++-- .../Controller/FavoritesControllerTest.php | 902 +++++---- tests/Unit/Controller/PageControllerTest.php | 73 +- .../Unit/Controller/PhotosControllerTest.php | 416 ++-- .../PublicFavoritePageControllerTest.php | 138 +- .../PublicFavoritesApiControllerTest.php | 133 +- .../Unit/Controller/TracksControllerTest.php | 546 +++--- tests/Unit/Helper/ExifGeoDataTest.php | 78 +- 82 files changed, 9260 insertions(+), 9533 deletions(-) diff --git a/appinfo/routes.php b/appinfo/routes.php index 898b40d7c..c60120ea4 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -8,32 +8,32 @@ * it's instantiated in there */ return [ - 'routes' => [ - ['name' => 'page#index', 'url' => '/', 'verb' => 'GET'], - ['name' => 'page#indexMyMap', 'url' => '/m/{myMapId}', 'verb' => 'GET'], - ['name' => 'page#do_echo', 'url' => '/echo', 'verb' => 'POST'], - ['name' => 'page#openGeoLink', 'url' => '/openGeoLink/{url}', 'verb' => 'GET'], - ['name' => 'public_favorite_page#sharedFavoritesCategory', 'url' => '/s/favorites/{token}', 'verb' => 'GET'], + 'routes' => [ + ['name' => 'page#index', 'url' => '/', 'verb' => 'GET'], + ['name' => 'page#indexMyMap', 'url' => '/m/{myMapId}', 'verb' => 'GET'], + ['name' => 'page#do_echo', 'url' => '/echo', 'verb' => 'POST'], + ['name' => 'page#openGeoLink', 'url' => '/openGeoLink/{url}', 'verb' => 'GET'], + ['name' => 'public_favorite_page#sharedFavoritesCategory', 'url' => '/s/favorites/{token}', 'verb' => 'GET'], ['name' => 'PublicPage#showShare', 'url' => '/s/{token}', 'verb' => 'GET'], ['name' => 'PublicPage#showAuthenticate', 'url' => '/s/{token}/authenticate/{redirect}', 'verb' => 'GET'], ['name' => 'PublicPage#authenticate', 'url' => '/s/{token}/authenticate/{redirect}', 'verb' => 'POST'], - // utils - ['name' => 'utils#getOptionsValues', 'url' => '/getOptionsValues', 'verb' => 'GET'], - ['name' => 'utils#saveOptionValue', 'url' => '/saveOptionValue', 'verb' => 'POST'], - ['name' => 'utils#setRoutingSettings', 'url' => '/setRoutingSettings', 'verb' => 'POST'], - ['name' => 'utils#getTrafficStyle', 'url' => '/style/traffic', 'verb' => 'GET'], + // utils + ['name' => 'utils#getOptionsValues', 'url' => '/getOptionsValues', 'verb' => 'GET'], + ['name' => 'utils#saveOptionValue', 'url' => '/saveOptionValue', 'verb' => 'POST'], + ['name' => 'utils#setRoutingSettings', 'url' => '/setRoutingSettings', 'verb' => 'POST'], + ['name' => 'utils#getTrafficStyle', 'url' => '/style/traffic', 'verb' => 'GET'], ['name' => 'PublicUtils#getOptionsValues', 'url' => '/s/{token}/getOptionsValues', 'verb' => 'GET'], ['name' => 'PublicUtils#saveOptionValue', 'url' => '/s/{token}/saveOptionValue', 'verb' => 'POST'], ['name' => 'PublicUtils#setRoutingSettings', 'url' => '/s/{token}/setRoutingSettings', 'verb' => 'POST'], ['name' => 'PublicUtils#getTrafficStyle', 'url' => '/s/{token}/style/traffic', 'verb' => 'GET'], - // photos - ['name' => 'photos#getPhotos', 'url' => '/photos', 'verb' => 'GET'], - ['name' => 'photos#getNonLocalizedPhotos', 'url' => '/photos/nonlocalized', 'verb' => 'GET'], - ['name' => 'photos#placePhotos', 'url' => '/photos', 'verb' => 'POST'], - ['name' => 'photos#resetPhotosCoords', 'url' => '/photos', 'verb' => 'DELETE'], + // photos + ['name' => 'photos#getPhotos', 'url' => '/photos', 'verb' => 'GET'], + ['name' => 'photos#getNonLocalizedPhotos', 'url' => '/photos/nonlocalized', 'verb' => 'GET'], + ['name' => 'photos#placePhotos', 'url' => '/photos', 'verb' => 'POST'], + ['name' => 'photos#resetPhotosCoords', 'url' => '/photos', 'verb' => 'DELETE'], ['name' => 'photos#clearCache', 'url' => '/photos/clearCache', 'verb' => 'GET'], ['name' => 'photos#getBackgroundJobStatus', 'url' => '/photos/backgroundJobStatus', 'verb' => 'GET'], @@ -41,51 +41,51 @@ ['name' => 'PublicPhotos#getNonLocalizedPhotos', 'url' => '/s/{token}/photos/nonlocalized', 'verb' => 'GET'], ['name' => 'PublicPhotos#clearCache', 'url' => '/s/{token}/photos/clearCache', 'verb' => 'GET'], - // contacts - ['name' => 'contacts#getContacts', 'url' => '/contacts', 'verb' => 'GET'], - ['name' => 'contacts#searchContacts', 'url' => '/contacts-search', 'verb' => 'GET'], - ['name' => 'contacts#placeContact', 'url' => '/contacts/{bookid}/{uri}', 'verb' => 'PUT'], + // contacts + ['name' => 'contacts#getContacts', 'url' => '/contacts', 'verb' => 'GET'], + ['name' => 'contacts#searchContacts', 'url' => '/contacts-search', 'verb' => 'GET'], + ['name' => 'contacts#placeContact', 'url' => '/contacts/{bookid}/{uri}', 'verb' => 'PUT'], ['name' => 'contacts#addContactToMap', 'url' => '/contacts/{bookid}/{uri}/add-to-map/', 'verb' => 'PUT'], - ['name' => 'contacts#deleteContactAddress', 'url' => '/contacts/{bookid}/{uri}', 'verb' => 'DELETE'], - ['name' => 'contacts#getContactLetterAvatar', 'url' => '/contacts-avatar', 'verb' => 'GET'], + ['name' => 'contacts#deleteContactAddress', 'url' => '/contacts/{bookid}/{uri}', 'verb' => 'DELETE'], + ['name' => 'contacts#getContactLetterAvatar', 'url' => '/contacts-avatar', 'verb' => 'GET'], ['name' => 'PublicContacts#getContacts', 'url' => '/s/{token}/contacts', 'verb' => 'GET'], ['name' => 'PublicContacts#getContactLetterAvatar', 'url' => '/s/{token}/contacts-avatar', 'verb' => 'GET'], - // routing - ['name' => 'routing#exportRoute', 'url' => '/exportRoute', 'verb' => 'POST'], - - // favorites API - [ - 'name' => 'favorites_api#preflighted_cors', - 'url' => '/api/1.0/favorites{path}', - 'verb' => 'OPTIONS', - 'requirements' => ['path' => '.+'] - ], - ['name' => 'favorites_api#getFavorites', 'url' => '/api/{apiversion}/favorites', 'verb' => 'GET'], - ['name' => 'favorites_api#addFavorite', 'url' => '/api/{apiversion}/favorites', 'verb' => 'POST'], - ['name' => 'favorites_api#editFavorite', 'url' => '/api/{apiversion}/favorites/{id}', 'verb' => 'PUT'], - ['name' => 'favorites_api#deleteFavorite', 'url' => '/api/{apiversion}/favorites/{id}', 'verb' => 'DELETE'], - - // public favorites API - [ - 'name' => 'favorites_api#preflighted_cors', - 'url' => '/api/1.0/public/favorites{path}', - 'verb' => 'OPTIONS', - 'requirements' => ['path' => '.+'] - ], - ['name' => 'public_favorites_api#getFavorites', 'url' => '/api/1.0/public/{token}/favorites', 'verb' => 'GET'], -// ['name' => 'public_favorites_api#addFavorite', 'url' => '/api/1.0/public/{token}/favorites', 'verb' => 'POST'], -// ['name' => 'public_favorites_api#editFavorite', 'url' => '/api/1.0/public/{token}/favorites/{id}', 'verb' => 'PUT'], -// ['name' => 'public_favorites_api#deleteFavorite', 'url' => '/api/1.0/public/{token}/favorites/{id}', 'verb' => 'DELETE'], - - // favorites - ['name' => 'favorites#getFavorites', 'url' => '/favorites', 'verb' => 'GET'], - ['name' => 'favorites#addFavorite', 'url' => '/favorite', 'verb' => 'POST'], + // routing + ['name' => 'routing#exportRoute', 'url' => '/exportRoute', 'verb' => 'POST'], + + // favorites API + [ + 'name' => 'favorites_api#preflighted_cors', + 'url' => '/api/1.0/favorites{path}', + 'verb' => 'OPTIONS', + 'requirements' => ['path' => '.+'] + ], + ['name' => 'favorites_api#getFavorites', 'url' => '/api/{apiversion}/favorites', 'verb' => 'GET'], + ['name' => 'favorites_api#addFavorite', 'url' => '/api/{apiversion}/favorites', 'verb' => 'POST'], + ['name' => 'favorites_api#editFavorite', 'url' => '/api/{apiversion}/favorites/{id}', 'verb' => 'PUT'], + ['name' => 'favorites_api#deleteFavorite', 'url' => '/api/{apiversion}/favorites/{id}', 'verb' => 'DELETE'], + + // public favorites API + [ + 'name' => 'favorites_api#preflighted_cors', + 'url' => '/api/1.0/public/favorites{path}', + 'verb' => 'OPTIONS', + 'requirements' => ['path' => '.+'] + ], + ['name' => 'public_favorites_api#getFavorites', 'url' => '/api/1.0/public/{token}/favorites', 'verb' => 'GET'], + // ['name' => 'public_favorites_api#addFavorite', 'url' => '/api/1.0/public/{token}/favorites', 'verb' => 'POST'], + // ['name' => 'public_favorites_api#editFavorite', 'url' => '/api/1.0/public/{token}/favorites/{id}', 'verb' => 'PUT'], + // ['name' => 'public_favorites_api#deleteFavorite', 'url' => '/api/1.0/public/{token}/favorites/{id}', 'verb' => 'DELETE'], + + // favorites + ['name' => 'favorites#getFavorites', 'url' => '/favorites', 'verb' => 'GET'], + ['name' => 'favorites#addFavorite', 'url' => '/favorite', 'verb' => 'POST'], ['name' => 'favorites#addFavorites', 'url' => '/favorites', 'verb' => 'POST'], - ['name' => 'favorites#editFavorite', 'url' => '/favorites/{id}', 'verb' => 'PUT'], - ['name' => 'favorites#deleteFavorite', 'url' => '/favorites/{id}', 'verb' => 'DELETE'], - ['name' => 'favorites#deleteFavorites', 'url' => '/favorites', 'verb' => 'DELETE'], + ['name' => 'favorites#editFavorite', 'url' => '/favorites/{id}', 'verb' => 'PUT'], + ['name' => 'favorites#deleteFavorite', 'url' => '/favorites/{id}', 'verb' => 'DELETE'], + ['name' => 'favorites#deleteFavorites', 'url' => '/favorites', 'verb' => 'DELETE'], ['name' => 'PublicFavorites#getFavorites', 'url' => '/s/{token}/favorites', 'verb' => 'GET'], ['name' => 'PublicFavorites#addFavorite', 'url' => '/s/{token}/favorite', 'verb' => 'POST'], @@ -94,54 +94,54 @@ ['name' => 'PublicFavorites#deleteFavorite', 'url' => '/s/{token}/favorites/{id}', 'verb' => 'DELETE'], ['name' => 'PublicFavorites#deleteFavorites', 'url' => '/s/{token}/favorites', 'verb' => 'DELETE'], - // favorite categories - ['name' => 'favorites#renameCategories', 'url' => '/favorites-category', 'verb' => 'PUT'], - ['name' => 'favorites#getSharedCategories', 'url' => '/favorites-category/shared', 'verb' => 'GET'], - ['name' => 'favorites#shareCategory', 'url' => '/favorites-category/{category}/share', 'verb' => 'POST'], - ['name' => 'favorites#unShareCategory', 'url' => '/favorites-category/{category}/un-share', 'verb' => 'POST'], + // favorite categories + ['name' => 'favorites#renameCategories', 'url' => '/favorites-category', 'verb' => 'PUT'], + ['name' => 'favorites#getSharedCategories', 'url' => '/favorites-category/shared', 'verb' => 'GET'], + ['name' => 'favorites#shareCategory', 'url' => '/favorites-category/{category}/share', 'verb' => 'POST'], + ['name' => 'favorites#unShareCategory', 'url' => '/favorites-category/{category}/un-share', 'verb' => 'POST'], ['name' => 'favorites#addShareCategoryToMap', 'url' => '/favorites-category/{category}/add-to-map/{targetMapId}', 'verb' => 'PUT'], ['name' => 'favorites#removeShareCategoryFromMap', 'url' => '/favorites-category/{category}/', 'verb' => 'DELETE'], - ['name' => 'favorites#exportFavorites', 'url' => '/export/favorites', 'verb' => 'POST'], - ['name' => 'favorites#importFavorites', 'url' => '/import/favorites', 'verb' => 'POST'], + ['name' => 'favorites#exportFavorites', 'url' => '/export/favorites', 'verb' => 'POST'], + ['name' => 'favorites#importFavorites', 'url' => '/import/favorites', 'verb' => 'POST'], ['name' => 'PublicFavorites#renameCategories', 'url' => '/s/{token}/favorites-category', 'verb' => 'PUT'], ['name' => 'PublicFavorites#getSharedCategories', 'url' => '/s/{token}/favorites-category/shared', 'verb' => 'GET'], - // tracks - ['name' => 'tracks#getTracks', 'url' => '/tracks', 'verb' => 'GET'], - ['name' => 'tracks#getTrackFileContent', 'url' => '/tracks/{id}', 'verb' => 'GET'], + // tracks + ['name' => 'tracks#getTracks', 'url' => '/tracks', 'verb' => 'GET'], + ['name' => 'tracks#getTrackFileContent', 'url' => '/tracks/{id}', 'verb' => 'GET'], ['name' => 'tracks#getTrackContentByFileId', 'url' => '/tracks/file/{id}', 'verb' => 'GET'], - ['name' => 'tracks#editTrack', 'url' => '/tracks/{id}', 'verb' => 'PUT'], + ['name' => 'tracks#editTrack', 'url' => '/tracks/{id}', 'verb' => 'PUT'], ['name' => 'PublicTracks#getTracks', 'url' => '/s/{token}/tracks', 'verb' => 'GET'], ['name' => 'PublicTracks#getTrackFileContent', 'url' => '/s/{token}/tracks/{id}', 'verb' => 'GET'], ['name' => 'PublicTracks#getTrackContentByFileId', 'url' => '/s/{token}/tracks/file/{id}', 'verb' => 'GET'], ['name' => 'PublicTracks#editTrack', 'url' => '/s/{token}/tracks/{id}', 'verb' => 'PUT'], - // devices API - [ - 'name' => 'devices_api#preflighted_cors', - 'url' => '/api/1.0/devices{path}', - 'verb' => 'OPTIONS', - 'requirements' => ['path' => '.+'] - ], - ['name' => 'devices_api#getDevices', 'url' => '/api/{apiversion}/devices', 'verb' => 'GET'], - ['name' => 'devices_api#getDevicePoints', 'url' => '/api/{apiversion}/devices/{id}', 'verb' => 'GET'], - ['name' => 'devices_api#addDevicePoint', 'url' => '/api/{apiversion}/devices', 'verb' => 'POST'], - ['name' => 'devices_api#editDevice', 'url' => '/api/{apiversion}/devices/{id}', 'verb' => 'PUT'], - ['name' => 'devices_api#deleteDevice', 'url' => '/api/{apiversion}/devices/{id}', 'verb' => 'DELETE'], - - // devices - ['name' => 'devices#getDevices', 'url' => '/devices', 'verb' => 'GET'], + // devices API + [ + 'name' => 'devices_api#preflighted_cors', + 'url' => '/api/1.0/devices{path}', + 'verb' => 'OPTIONS', + 'requirements' => ['path' => '.+'] + ], + ['name' => 'devices_api#getDevices', 'url' => '/api/{apiversion}/devices', 'verb' => 'GET'], + ['name' => 'devices_api#getDevicePoints', 'url' => '/api/{apiversion}/devices/{id}', 'verb' => 'GET'], + ['name' => 'devices_api#addDevicePoint', 'url' => '/api/{apiversion}/devices', 'verb' => 'POST'], + ['name' => 'devices_api#editDevice', 'url' => '/api/{apiversion}/devices/{id}', 'verb' => 'PUT'], + ['name' => 'devices_api#deleteDevice', 'url' => '/api/{apiversion}/devices/{id}', 'verb' => 'DELETE'], + + // devices + ['name' => 'devices#getDevices', 'url' => '/devices', 'verb' => 'GET'], ['name' => 'devices#getDevicesByTokens', 'url' => '/devices/by-token', 'verb' => 'GET'], - ['name' => 'devices#getDevicePoints', 'url' => '/devices/{id}', 'verb' => 'GET'], - ['name' => 'devices#addDevicePoint', 'url' => '/devices', 'verb' => 'POST'], - ['name' => 'devices#editDevice', 'url' => '/devices/{id}', 'verb' => 'PUT'], - ['name' => 'devices#deleteDevice', 'url' => '/devices/{id}', 'verb' => 'DELETE'], + ['name' => 'devices#getDevicePoints', 'url' => '/devices/{id}', 'verb' => 'GET'], + ['name' => 'devices#addDevicePoint', 'url' => '/devices', 'verb' => 'POST'], + ['name' => 'devices#editDevice', 'url' => '/devices/{id}', 'verb' => 'PUT'], + ['name' => 'devices#deleteDevice', 'url' => '/devices/{id}', 'verb' => 'DELETE'], ['name' => 'devices#shareDevice', 'url' => '/devices/{id}/share', 'verb' => 'POST'], - ['name' => 'devices#exportDevices', 'url' => '/export/devices', 'verb' => 'POST'], - ['name' => 'devices#importDevices', 'url' => '/import/devices', 'verb' => 'POST'], + ['name' => 'devices#exportDevices', 'url' => '/export/devices', 'verb' => 'POST'], + ['name' => 'devices#importDevices', 'url' => '/import/devices', 'verb' => 'POST'], // devices sharing ['name' => 'devices#getSharedDevices', 'url' => '/devices/s/', 'verb' => 'GET'], // ['name' => 'devices#shareDevice', 'url' => '/devices/s/', 'verb' => 'POST'], @@ -149,10 +149,10 @@ ['name' => 'devices#addSharedDeviceToMap', 'url' => '/devices/s/{token}/map-link/{targetMapId}', 'verb' => 'POST'], ['name' => 'devices#removeSharedDeviceFromMap', 'url' => '/devices/s/{token}/map-link/{targetMapId}', 'verb' => 'DELETE'], - //MyMaps - ['name' => 'my_maps#getMyMaps', 'url' => '/maps', 'verb' => 'GET'], - ['name' => 'my_maps#addMyMap' , 'url' => '/maps', 'verb' => 'POST'], - ['name' => 'my_maps#updateMyMap' , 'url' => '/maps/{id}', 'verb' => 'PUT'], - ['name' => 'my_maps#deleteMyMap' , 'url' => '/maps/{id}', 'verb' => 'DELETE'], - ] + //MyMaps + ['name' => 'my_maps#getMyMaps', 'url' => '/maps', 'verb' => 'GET'], + ['name' => 'my_maps#addMyMap' , 'url' => '/maps', 'verb' => 'POST'], + ['name' => 'my_maps#updateMyMap' , 'url' => '/maps/{id}', 'verb' => 'PUT'], + ['name' => 'my_maps#deleteMyMap' , 'url' => '/maps/{id}', 'verb' => 'DELETE'], + ] ]; diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index d5fd91622..e867e6f62 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -11,36 +11,34 @@ namespace OCA\Maps\AppInfo; - +use OCA\DAV\Events\CardCreatedEvent; +use OCA\DAV\Events\CardDeletedEvent; +use OCA\DAV\Events\CardUpdatedEvent; +use OCA\Files\Event\LoadAdditionalScriptsEvent; use OCA\Files\Event\LoadSidebar; +use OCA\Maps\Hooks\FileHooks; +use OCA\Maps\Listener\CardCreatedListener; +use OCA\Maps\Listener\CardDeletedListener; +use OCA\Maps\Listener\CardUpdatedListener; +use OCA\Maps\Listener\LoadAdditionalScriptsListener; use OCA\Maps\Listener\LoadSidebarListener; -use \OCP\AppFramework\App; +use OCA\Maps\Service\PhotofilesService; +use OCA\Maps\Service\TracksService; +use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; +use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCP\AppFramework\Http\EmptyFeaturePolicy; use OCP\EventDispatcher\IEventDispatcher; -use \OCP\IServerContainer; -use OCA\Maps\Hooks\FileHooks; -use OCA\Maps\Service\PhotofilesService; -use OCA\Maps\Service\TracksService; -use OCP\AppFramework\Bootstrap\IRegistrationContext; -use OCA\Files\Event\LoadAdditionalScriptsEvent; -use OCA\DAV\Events\CardCreatedEvent; -use OCA\DAV\Events\CardUpdatedEvent; -use OCA\DAV\Events\CardDeletedEvent; -use OCA\Maps\Listener\LoadAdditionalScriptsListener; -use OCA\Maps\Listener\CardCreatedListener; -use OCA\Maps\Listener\CardUpdatedListener; -use OCA\Maps\Listener\CardDeletedListener; +use OCP\IServerContainer; use OCP\Security\FeaturePolicy\AddFeaturePolicyEvent; - class Application extends App implements IBootstrap { public const APP_ID = 'maps'; - public function __construct (array $urlParams=array()) { - parent::__construct('maps', $urlParams); - } + public function __construct(array $urlParams = []) { + parent::__construct('maps', $urlParams); + } public function register(IRegistrationContext $context): void { // ... registration logic goes here ... @@ -73,7 +71,7 @@ public function register(IRegistrationContext $context): void { public function boot(IBootContext $context): void { // ... boot logic goes here ... - $context->getAppContainer()->registerService('FileHooks', function($c) { + $context->getAppContainer()->registerService('FileHooks', function ($c) { return new FileHooks( $c->query(IServerContainer::class)->getRootFolder(), \OC::$server->query(PhotofilesService::class), diff --git a/lib/BackgroundJob/AddPhotoJob.php b/lib/BackgroundJob/AddPhotoJob.php index 55d8e7923..0871078c3 100644 --- a/lib/BackgroundJob/AddPhotoJob.php +++ b/lib/BackgroundJob/AddPhotoJob.php @@ -12,17 +12,13 @@ namespace OCA\Maps\BackgroundJob; -use \OCP\BackgroundJob\QueuedJob; -use \OCP\BackgroundJob\IJobList; -use \OCP\AppFramework\Utility\ITimeFactory; -use OCP\ICache; -use OCP\ICacheFactory; -use OCP\IUserManager; -use OCP\IConfig; -use OCP\Files\IRootFolder; - use OCA\Maps\Service\PhotofilesService; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\BackgroundJob\QueuedJob; +use OCP\Files\IRootFolder; +use OCP\ICache; +use OCP\ICacheFactory; class AddPhotoJob extends QueuedJob { @@ -38,35 +34,35 @@ class AddPhotoJob extends QueuedJob { /** @var ICache */ private ICache $backgroundJobCache; - /** - * UserInstallScanJob constructor. - * - * A QueuedJob to scan user storage for photos and tracks - * + /** + * UserInstallScanJob constructor. + * + * A QueuedJob to scan user storage for photos and tracks + * * @param ITimeFactory $timeFactory * @param PhotofilesService $photofilesService - */ - public function __construct(ITimeFactory $timeFactory, - IRootFolder $root, - PhotofilesService $photofilesService, - ICacheFactory $cacheFactory) { - parent::__construct($timeFactory); - $this->photofilesService = $photofilesService; - $this->root = $root; + */ + public function __construct(ITimeFactory $timeFactory, + IRootFolder $root, + PhotofilesService $photofilesService, + ICacheFactory $cacheFactory) { + parent::__construct($timeFactory); + $this->photofilesService = $photofilesService; + $this->root = $root; $this->cacheFactory = $cacheFactory; $this->backgroundJobCache = $this->cacheFactory->createDistributed('maps:background-jobs'); - } + } - public function run($arguments) { - $userFolder = $this->root->getUserFolder($arguments['userId']); - $files = $userFolder->getById($arguments['photoId']); - if (empty($files)) { - return; - } - $file = array_shift($files); - $this->photofilesService->addPhotoNow($file, $arguments['userId']); + public function run($arguments) { + $userFolder = $this->root->getUserFolder($arguments['userId']); + $files = $userFolder->getById($arguments['photoId']); + if (empty($files)) { + return; + } + $file = array_shift($files); + $this->photofilesService->addPhotoNow($file, $arguments['userId']); $counter = $this->backgroundJobCache->get('recentlyAdded:'.$arguments['userId']) ?? 0; - $this->backgroundJobCache->set('recentlyAdded:'.$arguments['userId'], (int) $counter + 1, 60 * 60 * 3); - } + $this->backgroundJobCache->set('recentlyAdded:'.$arguments['userId'], (int)$counter + 1, 60 * 60 * 3); + } } diff --git a/lib/BackgroundJob/LaunchUsersInstallScanJob.php b/lib/BackgroundJob/LaunchUsersInstallScanJob.php index ecbda8310..047a611a7 100644 --- a/lib/BackgroundJob/LaunchUsersInstallScanJob.php +++ b/lib/BackgroundJob/LaunchUsersInstallScanJob.php @@ -12,35 +12,33 @@ namespace OCA\Maps\BackgroundJob; -use \OCP\BackgroundJob\QueuedJob; -use \OCP\BackgroundJob\IJobList; -use \OCP\AppFramework\Utility\ITimeFactory; -use OCP\IUserManager; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\BackgroundJob\IJobList; +use OCP\BackgroundJob\QueuedJob; use OCP\IUser; - -use \OCA\Maps\BackgroundJob\UserInstallScanJob; +use OCP\IUserManager; class LaunchUsersInstallScanJob extends QueuedJob { - private $jobList; - - /** - * LaunchUsersInstallScanJob constructor. - * - * A QueuedJob to launch a scan job for each user - * - * @param IJobList $jobList - */ - public function __construct(ITimeFactory $timeFactory, IJobList $jobList, IUserManager $userManager) { - parent::__construct($timeFactory); - $this->jobList = $jobList; - $this->userManager = $userManager; - } - - public function run($arguments) { - \OC::$server->getLogger()->debug('Launch users install scan jobs cronjob executed'); - $this->userManager->callForSeenUsers(function (IUser $user) { - $this->jobList->add(UserInstallScanJob::class, ['userId' => $user->getUID()]); - }); - } + private $jobList; + + /** + * LaunchUsersInstallScanJob constructor. + * + * A QueuedJob to launch a scan job for each user + * + * @param IJobList $jobList + */ + public function __construct(ITimeFactory $timeFactory, IJobList $jobList, IUserManager $userManager) { + parent::__construct($timeFactory); + $this->jobList = $jobList; + $this->userManager = $userManager; + } + + public function run($arguments) { + \OC::$server->getLogger()->debug('Launch users install scan jobs cronjob executed'); + $this->userManager->callForSeenUsers(function (IUser $user) { + $this->jobList->add(UserInstallScanJob::class, ['userId' => $user->getUID()]); + }); + } } diff --git a/lib/BackgroundJob/LookupMissingGeoJob.php b/lib/BackgroundJob/LookupMissingGeoJob.php index 139efd1cb..4dc977f51 100644 --- a/lib/BackgroundJob/LookupMissingGeoJob.php +++ b/lib/BackgroundJob/LookupMissingGeoJob.php @@ -12,39 +12,39 @@ namespace OCA\Maps\BackgroundJob; -use \OCA\Maps\Service\AddressService; -use \OCP\BackgroundJob\QueuedJob; -use \OCP\BackgroundJob\IJobList; -use \OCP\AppFramework\Utility\ITimeFactory; +use OCA\Maps\Service\AddressService; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\BackgroundJob\IJobList; +use OCP\BackgroundJob\QueuedJob; class LookupMissingGeoJob extends QueuedJob { - /** @var AddressService */ - private $addressService; - - /** @var AddressService */ - private $jobList; - - /** - * LookupMissingGeoJob constructor. - * - * A QueuedJob to lookup missing geo information of addresses - * - * @param AddressService $service - * @param IJobList $jobList - */ - public function __construct(ITimeFactory $timeFactory, AddressService $service, IJobList $jobList) { - parent::__construct($timeFactory); - $this->addressService = $service; - $this->jobList = $jobList; - } - - public function run($arguments) { - \OC::$server->getLogger()->debug('Maps address lookup cronjob executed'); - // lookup at most 200 addresses - if (!$this->addressService->lookupMissingGeo(200)){ - // if not all addresses where looked up successfully add a new job for next time - $this->jobList->add(LookupMissingGeoJob::class, []); - } - } + /** @var AddressService */ + private $addressService; + + /** @var AddressService */ + private $jobList; + + /** + * LookupMissingGeoJob constructor. + * + * A QueuedJob to lookup missing geo information of addresses + * + * @param AddressService $service + * @param IJobList $jobList + */ + public function __construct(ITimeFactory $timeFactory, AddressService $service, IJobList $jobList) { + parent::__construct($timeFactory); + $this->addressService = $service; + $this->jobList = $jobList; + } + + public function run($arguments) { + \OC::$server->getLogger()->debug('Maps address lookup cronjob executed'); + // lookup at most 200 addresses + if (!$this->addressService->lookupMissingGeo(200)) { + // if not all addresses where looked up successfully add a new job for next time + $this->jobList->add(LookupMissingGeoJob::class, []); + } + } } diff --git a/lib/BackgroundJob/UpdatePhotoByFileJob.php b/lib/BackgroundJob/UpdatePhotoByFileJob.php index 656210a8d..0d45aa9c4 100644 --- a/lib/BackgroundJob/UpdatePhotoByFileJob.php +++ b/lib/BackgroundJob/UpdatePhotoByFileJob.php @@ -12,17 +12,13 @@ namespace OCA\Maps\BackgroundJob; -use \OCP\BackgroundJob\QueuedJob; -use \OCP\BackgroundJob\IJobList; -use \OCP\AppFramework\Utility\ITimeFactory; -use OCP\ICache; -use OCP\ICacheFactory; -use OCP\IUserManager; -use OCP\IConfig; -use OCP\Files\IRootFolder; - use OCA\Maps\Service\PhotofilesService; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\BackgroundJob\QueuedJob; +use OCP\Files\IRootFolder; +use OCP\ICache; +use OCP\ICacheFactory; class UpdatePhotoByFileJob extends QueuedJob { @@ -38,35 +34,35 @@ class UpdatePhotoByFileJob extends QueuedJob { /** @var ICache */ private ICache $backgroundJobCache; - /** - * UserInstallScanJob constructor. - * - * A QueuedJob to scan user storage for photos and tracks - * - * @param ITimeFactory $timeFactory + /** + * UserInstallScanJob constructor. + * + * A QueuedJob to scan user storage for photos and tracks + * + * @param ITimeFactory $timeFactory * @param PhotofilesService $photofilesService - */ - public function __construct(ITimeFactory $timeFactory, - IRootFolder $root, - PhotofilesService $photofilesService, - ICacheFactory $cacheFactory) { - parent::__construct($timeFactory); - $this->photofilesService = $photofilesService; - $this->root = $root; + */ + public function __construct(ITimeFactory $timeFactory, + IRootFolder $root, + PhotofilesService $photofilesService, + ICacheFactory $cacheFactory) { + parent::__construct($timeFactory); + $this->photofilesService = $photofilesService; + $this->root = $root; $this->cacheFactory = $cacheFactory; $this->backgroundJobCache = $this->cacheFactory->createDistributed('maps:background-jobs'); - } + } - public function run($arguments) { - $userFolder = $this->root->getUserFolder($arguments['userId']); - $files = $userFolder->getById($arguments['fileId']); - if (empty($files)) { - return; - } - $file = array_shift($files); - $this->photofilesService->updateByFileNow($file); + public function run($arguments) { + $userFolder = $this->root->getUserFolder($arguments['userId']); + $files = $userFolder->getById($arguments['fileId']); + if (empty($files)) { + return; + } + $file = array_shift($files); + $this->photofilesService->updateByFileNow($file); $counter = $this->backgroundJobCache->get('recentlyUpdated:'.$arguments['userId']) ?? 0; - $this->backgroundJobCache->set('recentlyUpdated:'.$arguments['userId'], (int) $counter + 1, 60 * 60 * 3); - } + $this->backgroundJobCache->set('recentlyUpdated:'.$arguments['userId'], (int)$counter + 1, 60 * 60 * 3); + } } diff --git a/lib/BackgroundJob/UserInstallScanJob.php b/lib/BackgroundJob/UserInstallScanJob.php index d53e43c02..73d190089 100644 --- a/lib/BackgroundJob/UserInstallScanJob.php +++ b/lib/BackgroundJob/UserInstallScanJob.php @@ -12,68 +12,68 @@ namespace OCA\Maps\BackgroundJob; -use \OCP\BackgroundJob\QueuedJob; -use \OCP\BackgroundJob\IJobList; -use \OCP\AppFramework\Utility\ITimeFactory; -use OCP\IUserManager; -use OCP\IConfig; - use OCA\Maps\Service\PhotofilesService; use OCA\Maps\Service\TracksService; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\BackgroundJob\IJobList; +use OCP\BackgroundJob\QueuedJob; + +use OCP\IConfig; +use OCP\IUserManager; class UserInstallScanJob extends QueuedJob { - private IJobList $jobList; - private IConfig $config; - private IUserManager $userManager; - private PhotofilesService $photofilesService; - private TracksService $tracksService; + private IJobList $jobList; + private IConfig $config; + private IUserManager $userManager; + private PhotofilesService $photofilesService; + private TracksService $tracksService; - /** - * UserInstallScanJob constructor. - * - * A QueuedJob to scan user storage for photos and tracks - * - * @param IJobList $jobList - */ - public function __construct(ITimeFactory $timeFactory, IJobList $jobList, - IUserManager $userManager, - IConfig $config, - PhotofilesService $photofilesService, - TracksService $tracksService) { - parent::__construct($timeFactory); - $this->config = $config; - $this->jobList = $jobList; - $this->userManager = $userManager; - $this->photofilesService = $photofilesService; - $this->tracksService = $tracksService; - } + /** + * UserInstallScanJob constructor. + * + * A QueuedJob to scan user storage for photos and tracks + * + * @param IJobList $jobList + */ + public function __construct(ITimeFactory $timeFactory, IJobList $jobList, + IUserManager $userManager, + IConfig $config, + PhotofilesService $photofilesService, + TracksService $tracksService) { + parent::__construct($timeFactory); + $this->config = $config; + $this->jobList = $jobList; + $this->userManager = $userManager; + $this->photofilesService = $photofilesService; + $this->tracksService = $tracksService; + } - public function run($arguments) { - $userId = $arguments['userId']; - \OC::$server->getLogger()->debug('Launch user install scan job for '.$userId.' cronjob executed'); - // scan photos and tracks for given user - $this->rescanUserPhotos($userId); - $this->rescanUserTracks($userId); - $this->config->setUserValue($userId, 'maps', 'installScanDone', 'yes'); - } + public function run($arguments) { + $userId = $arguments['userId']; + \OC::$server->getLogger()->debug('Launch user install scan job for '.$userId.' cronjob executed'); + // scan photos and tracks for given user + $this->rescanUserPhotos($userId); + $this->rescanUserTracks($userId); + $this->config->setUserValue($userId, 'maps', 'installScanDone', 'yes'); + } - private function rescanUserPhotos($userId) { - //$this->output->info('======== User '.$userId.' ========'."\n"); - $c = 1; - foreach ($this->photofilesService->rescan($userId) as $path) { - //$this->output->info('['.$c.'] Photo "'.$path.'" added'."\n"); - $c++; - } + private function rescanUserPhotos($userId) { + //$this->output->info('======== User '.$userId.' ========'."\n"); + $c = 1; + foreach ($this->photofilesService->rescan($userId) as $path) { + //$this->output->info('['.$c.'] Photo "'.$path.'" added'."\n"); + $c++; + } } - private function rescanUserTracks($userId) { - //$this->output->info('======== User '.$userId.' ========'."\n"); - $c = 1; - foreach ($this->tracksService->rescan($userId) as $path) { - //$this->output->info('['.$c.'] Track "'.$path.'" added'."\n"); - $c++; - } - } + private function rescanUserTracks($userId) { + //$this->output->info('======== User '.$userId.' ========'."\n"); + $c = 1; + foreach ($this->tracksService->rescan($userId) as $path) { + //$this->output->info('['.$c.'] Track "'.$path.'" added'."\n"); + $c++; + } + } } diff --git a/lib/Command/RegisterMimetypes.php b/lib/Command/RegisterMimetypes.php index 5d1b5d35a..e766cde36 100644 --- a/lib/Command/RegisterMimetypes.php +++ b/lib/Command/RegisterMimetypes.php @@ -13,44 +13,38 @@ namespace OCA\Maps\Command; use OCA\Maps\Service\MimetypeService; -use OCP\Encryption\IManager; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Input\InputOption; -use OCP\IConfig; - -use OCA\Maps\Service\PhotofilesService; class RegisterMimetypes extends Command { - protected MimetypeService $mimetypeService; + protected MimetypeService $mimetypeService; - public function __construct(MimetypeService $mimetypeService) { - parent::__construct(); - $this->mimetypeService = $mimetypeService; - } + public function __construct(MimetypeService $mimetypeService) { + parent::__construct(); + $this->mimetypeService = $mimetypeService; + } /** * @return void */ - protected function configure() { - $this->setName('maps:register-mimetypes') - ->setDescription('Registers the maps mimetypes for existing and new files.'); - } + protected function configure() { + $this->setName('maps:register-mimetypes') + ->setDescription('Registers the maps mimetypes for existing and new files.'); + } /** * @param InputInterface $input * @param OutputInterface $output * @return int */ - protected function execute(InputInterface $input, OutputInterface $output): int { - $this->output = $output; - $output->writeln("Register mimetypes for existing files"); + protected function execute(InputInterface $input, OutputInterface $output): int { + $this->output = $output; + $output->writeln('Register mimetypes for existing files'); $this->mimetypeService->registerForExistingFiles(); - $output->writeln("Register mimetypes for new files"); + $output->writeln('Register mimetypes for new files'); $this->mimetypeService->registerForNewFiles(); - return 0; - } + return 0; + } } diff --git a/lib/Command/RescanPhotos.php b/lib/Command/RescanPhotos.php index 8ec7294e5..6dac6b03d 100644 --- a/lib/Command/RescanPhotos.php +++ b/lib/Command/RescanPhotos.php @@ -12,85 +12,84 @@ namespace OCA\Maps\Command; +use OCA\Maps\Service\PhotofilesService; use OCP\Encryption\IManager; -use OCP\Files\NotFoundException; +use OCP\IConfig; use OCP\IUser; use OCP\IUserManager; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputOption; -use OCP\IConfig; -use OCA\Maps\Service\PhotofilesService; +use Symfony\Component\Console\Output\OutputInterface; class RescanPhotos extends Command { - protected IUserManager $userManager; - protected OutputInterface $output; - protected IManager $encryptionManager; - protected PhotofilesService $photofilesService; - protected IConfig $config; + protected IUserManager $userManager; + protected OutputInterface $output; + protected IManager $encryptionManager; + protected PhotofilesService $photofilesService; + protected IConfig $config; - public function __construct(IUserManager $userManager, - IManager $encryptionManager, - PhotofilesService $photofilesService, - IConfig $config) { - parent::__construct(); - $this->userManager = $userManager; - $this->encryptionManager = $encryptionManager; - $this->photofilesService = $photofilesService; - $this->config = $config; - } + public function __construct(IUserManager $userManager, + IManager $encryptionManager, + PhotofilesService $photofilesService, + IConfig $config) { + parent::__construct(); + $this->userManager = $userManager; + $this->encryptionManager = $encryptionManager; + $this->photofilesService = $photofilesService; + $this->config = $config; + } /** * @return void */ - protected function configure() { - $this->setName('maps:scan-photos') - ->setDescription('Rescan photos GPS exif data') - ->addArgument( - 'user_id', - InputArgument::OPTIONAL, - 'Rescan photos GPS exif data for the given user' - ) + protected function configure() { + $this->setName('maps:scan-photos') + ->setDescription('Rescan photos GPS exif data') + ->addArgument( + 'user_id', + InputArgument::OPTIONAL, + 'Rescan photos GPS exif data for the given user' + ) ->addOption( 'now', null, InputOption::VALUE_NONE, 'Dot the rescan now and not as background jobs. Doing it now might run out of memory.' ); - } + } /** * @param InputInterface $input * @param OutputInterface $output * @return int */ - protected function execute(InputInterface $input, OutputInterface $output): int { - if ($this->encryptionManager->isEnabled()) { - $output->writeln('Encryption is enabled. Aborted.'); - return 1; - } - $this->output = $output; - $userId = $input->getArgument('user_id'); + protected function execute(InputInterface $input, OutputInterface $output): int { + if ($this->encryptionManager->isEnabled()) { + $output->writeln('Encryption is enabled. Aborted.'); + return 1; + } + $this->output = $output; + $userId = $input->getArgument('user_id'); $inBackground = !($input->getOption('now') ?? true); if ($inBackground) { echo "Extracting coordinates from photo is performed in a BackgroundJob \n"; } - if ($userId === null) { - $this->userManager->callForSeenUsers(function (IUser $user) use ($inBackground) { - $this->rescanUserPhotos($user->getUID(), $inBackground); - }); - } else { - $user = $this->userManager->get($userId); - if ($user !== null) { - $this->rescanUserPhotos($userId, $inBackground); - } - } - return 0; - } + if ($userId === null) { + $this->userManager->callForSeenUsers(function (IUser $user) use ($inBackground) { + $this->rescanUserPhotos($user->getUID(), $inBackground); + }); + } else { + $user = $this->userManager->get($userId); + if ($user !== null) { + $this->rescanUserPhotos($userId, $inBackground); + } + } + return 0; + } /** * @param string $userId @@ -98,13 +97,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int * @return void * @throws \OCP\PreConditionNotMetException */ - private function rescanUserPhotos(string $userId, bool $inBackground=true) { - echo '======== User '.$userId.' ========'."\n"; - $c = 1; - foreach ($this->photofilesService->rescan($userId, $inBackground) as $path) { - echo '['.$c.'] Photo "'.$path.'" added'."\n"; - $c++; - } - $this->config->setUserValue($userId, 'maps', 'installScanDone', 'yes'); - } + private function rescanUserPhotos(string $userId, bool $inBackground = true) { + echo '======== User '.$userId.' ========'."\n"; + $c = 1; + foreach ($this->photofilesService->rescan($userId, $inBackground) as $path) { + echo '['.$c.'] Photo "'.$path.'" added'."\n"; + $c++; + } + $this->config->setUserValue($userId, 'maps', 'installScanDone', 'yes'); + } } diff --git a/lib/Command/RescanTracks.php b/lib/Command/RescanTracks.php index fc6eba723..b549bffee 100644 --- a/lib/Command/RescanTracks.php +++ b/lib/Command/RescanTracks.php @@ -12,73 +12,72 @@ namespace OCA\Maps\Command; +use OCA\Maps\Service\TracksService; use OCP\Encryption\IManager; -use OCP\Files\NotFoundException; +use OCP\IConfig; use OCP\IUser; use OCP\IUserManager; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use OCP\IConfig; -use OCA\Maps\Service\TracksService; +use Symfony\Component\Console\Output\OutputInterface; class RescanTracks extends Command { - protected IUserManager $userManager; - protected OutputInterface $output; - protected IManager $encryptionManager; - protected TracksService $tracksService; - protected IConfig $config; + protected IUserManager $userManager; + protected OutputInterface $output; + protected IManager $encryptionManager; + protected TracksService $tracksService; + protected IConfig $config; - public function __construct(IUserManager $userManager, - IManager $encryptionManager, - TracksService $tracksService, - IConfig $config) { - parent::__construct(); - $this->userManager = $userManager; - $this->encryptionManager = $encryptionManager; - $this->tracksService = $tracksService; - $this->config = $config; - } - protected function configure() { - $this->setName('maps:scan-tracks') - ->setDescription('Rescan track files') - ->addArgument( - 'user_id', - InputArgument::OPTIONAL, - 'Rescan track files for the given user' - ); - } + public function __construct(IUserManager $userManager, + IManager $encryptionManager, + TracksService $tracksService, + IConfig $config) { + parent::__construct(); + $this->userManager = $userManager; + $this->encryptionManager = $encryptionManager; + $this->tracksService = $tracksService; + $this->config = $config; + } + protected function configure() { + $this->setName('maps:scan-tracks') + ->setDescription('Rescan track files') + ->addArgument( + 'user_id', + InputArgument::OPTIONAL, + 'Rescan track files for the given user' + ); + } - protected function execute(InputInterface $input, OutputInterface $output) { - if ($this->encryptionManager->isEnabled()) { - $output->writeln('Encryption is enabled. Aborted.'); - return 1; - } - $this->output = $output; - $userId = $input->getArgument('user_id'); - if ($userId === null) { - $this->userManager->callForSeenUsers(function (IUser $user) { - $this->rescanUserTracks($user->getUID()); - }); - } else { - $user = $this->userManager->get($userId); - if ($user !== null) { - $this->rescanUserTracks($userId); - } - } - return 0; - } + protected function execute(InputInterface $input, OutputInterface $output) { + if ($this->encryptionManager->isEnabled()) { + $output->writeln('Encryption is enabled. Aborted.'); + return 1; + } + $this->output = $output; + $userId = $input->getArgument('user_id'); + if ($userId === null) { + $this->userManager->callForSeenUsers(function (IUser $user) { + $this->rescanUserTracks($user->getUID()); + }); + } else { + $user = $this->userManager->get($userId); + if ($user !== null) { + $this->rescanUserTracks($userId); + } + } + return 0; + } - private function rescanUserTracks($userId) { - echo '======== User '.$userId.' ========'."\n"; - $c = 1; - foreach ($this->tracksService->rescan($userId) as $path) { - echo '['.$c.'] Track "'.$path.'" added'."\n"; - $c++; - } - $this->config->setUserValue($userId, 'maps', 'installScanDone', 'yes'); - } + private function rescanUserTracks($userId) { + echo '======== User '.$userId.' ========'."\n"; + $c = 1; + foreach ($this->tracksService->rescan($userId) as $path) { + echo '['.$c.'] Track "'.$path.'" added'."\n"; + $c++; + } + $this->config->setUserValue($userId, 'maps', 'installScanDone', 'yes'); + } } diff --git a/lib/Controller/ContactsController.php b/lib/Controller/ContactsController.php index 4c75c95c6..814f8650d 100644 --- a/lib/Controller/ContactsController.php +++ b/lib/Controller/ContactsController.php @@ -13,22 +13,22 @@ namespace OCA\Maps\Controller; use OC\Files\Node\Node; +use OCA\DAV\CardDAV\CardDavBackend; +use OCA\Maps\Service\AddressService; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\DataDisplayResponse; +use OCP\AppFramework\Http\DataResponse; +use OCP\Contacts\IManager; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; -use OCP\IRequest; use OCP\IAvatarManager; -use OCP\AppFramework\Http\DataDisplayResponse; -use OCP\AppFramework\Http\DataResponse; -use OCP\ILogger; use OCP\IDBConnection; -use OCP\AppFramework\Controller; -use OCP\Contacts\IManager; -use OCA\Maps\Service\AddressService; -use \OCP\DB\QueryBuilder\IQueryBuilder; -use \OCA\DAV\CardDAV\CardDavBackend; +use OCP\ILogger; +use OCP\IRequest; use OCP\IURLGenerator; -use \Sabre\VObject\Property\Text; -use \Sabre\VObject\Reader; +use Sabre\VObject\Property\Text; +use Sabre\VObject\Reader; class ContactsController extends Controller { private $userId; @@ -40,8 +40,8 @@ class ContactsController extends Controller { private $cdBackend; private $avatarManager; private $root; - private $urlGenerator; - private $geoDistanceMax; // Max distance in meters to consider that 2 addresses are the same location + private $urlGenerator; + private $geoDistanceMax; // Max distance in meters to consider that 2 addresses are the same location /** * @param $AppName @@ -56,17 +56,17 @@ class ContactsController extends Controller { * @param IRootFolder $root */ public function __construct( - $AppName, - ILogger $logger, - IRequest $request, - IDBConnection $dbconnection, - IManager $contactsManager, - AddressService $addressService, - $UserId, - CardDavBackend $cdBackend, - IAvatarManager $avatarManager, - IRootFolder $root, - IURLGenerator $urlGenerator){ + $AppName, + ILogger $logger, + IRequest $request, + IDBConnection $dbconnection, + IManager $contactsManager, + AddressService $addressService, + $UserId, + CardDavBackend $cdBackend, + IAvatarManager $avatarManager, + IRootFolder $root, + IURLGenerator $urlGenerator) { parent::__construct($AppName, $request); $this->logger = $logger; $this->userId = $UserId; @@ -77,63 +77,63 @@ public function __construct( $this->qb = $dbconnection->getQueryBuilder(); $this->cdBackend = $cdBackend; $this->root = $root; - $this->urlGenerator = $urlGenerator; - $this->geoDistanceMax = 5; + $this->urlGenerator = $urlGenerator; + $this->geoDistanceMax = 5; + } + /** + * Converts a geo string as a float array + * @param string formatted as "lat;lon" + * @return float array containing [lat;lon] + */ + private function geoAsFloatArray($geo) { + $res = array_map(function ($value) {return floatval($value);}, explode(';', $geo)); + return $res; } - /** - * Converts a geo string as a float array - * @param string formatted as "lat;lon" - * @return float array containing [lat;lon] - */ - private function geoAsFloatArray($geo) { - $res = array_map(function($value) {return floatval($value);}, explode(";", $geo) ); - return $res; - } - /** - * check if geographical address is duplicated - * @param array containing contact's previous different addresses - * @param contact's address to check - * @return integer : -1 if address is new, index of duplicated address in other cases - */ - private function isNewAddress($prevGeo, $geo) { - if (empty($geo)) { // Address not converted to geo coords - return -1; - } - $result = -1; - $counter = 0; - foreach ($prevGeo as $prev) { - if ($this->getDistance($prev, $geo) <= $this->geoDistanceMax) { - $result = $counter; - break; - } - $counter++; - } - return $result; - } + /** + * check if geographical address is duplicated + * @param array containing contact's previous different addresses + * @param contact's address to check + * @return integer : -1 if address is new, index of duplicated address in other cases + */ + private function isNewAddress($prevGeo, $geo) { + if (empty($geo)) { // Address not converted to geo coords + return -1; + } + $result = -1; + $counter = 0; + foreach ($prevGeo as $prev) { + if ($this->getDistance($prev, $geo) <= $this->geoDistanceMax) { + $result = $counter; + break; + } + $counter++; + } + return $result; + } - /** - * get distance between two geo points - * @param GPS coordinates of first point - * @param GPS coordinates of second point - * @return Distance in meters between these two points - */ - private function getDistance($coordsA, $coordsB) { - if (empty($coordsA) || empty($coordsB) ) { - return 9E999; - } - $latA = deg2rad($coordsA[0]); - $lonA = deg2rad($coordsA[1]); - $latB = deg2rad($coordsB[0]); - $lonB = deg2rad($coordsB[1]); - $earthRadius = 6378137; // in m - $dlon = ($lonB - $lonA) / 2; - $dlat = ($latB - $latA) / 2; - $a = (sin($dlat) * sin($dlat)) + cos($latA) * cos($latB) * (sin($dlon) * sin($dlon -)); - $d = 2 * atan2(sqrt($a), sqrt(1 - $a)); - return $d * $earthRadius; - } + /** + * get distance between two geo points + * @param GPS coordinates of first point + * @param GPS coordinates of second point + * @return Distance in meters between these two points + */ + private function getDistance($coordsA, $coordsB) { + if (empty($coordsA) || empty($coordsB)) { + return 9E999; + } + $latA = deg2rad($coordsA[0]); + $lonA = deg2rad($coordsA[1]); + $latB = deg2rad($coordsB[0]); + $lonB = deg2rad($coordsB[1]); + $earthRadius = 6378137; // in m + $dlon = ($lonB - $lonA) / 2; + $dlat = ($latB - $latA) / 2; + $a = (sin($dlat) * sin($dlat)) + cos($latA) * cos($latB) * (sin($dlon) * sin($dlon + )); + $d = 2 * atan2(sqrt($a), sqrt(1 - $a)); + return $d * $earthRadius; + } /** * get contacts with coordinates @@ -144,12 +144,12 @@ private function getDistance($coordsA, $coordsB) { * @throws \OCP\Files\NotPermittedException * @throws \OC\User\NoUserException */ - public function getContacts($myMapId=null): DataResponse { + public function getContacts($myMapId = null): DataResponse { if (is_null($myMapId) || $myMapId === '') { $contacts = $this->contactsManager->search('', ['GEO', 'ADR'], ['types' => false]); $addressBooks = $this->contactsManager->getUserAddressBooks(); $result = []; - $userid = trim($this->userId); + $userid = trim($this->userId); foreach ($contacts as $c) { $addressBookUri = $addressBooks[$c['addressbook-key']]->getUri(); @@ -180,7 +180,7 @@ public function getContacts($myMapId=null): DataResponse { 'isDeletable' => true, 'isUpdateable' => true, ]; - } elseif (is_countable($geo) && count($geo)>0 && is_iterable($geo)) { + } elseif (is_countable($geo) && count($geo) > 0 && is_iterable($geo)) { foreach ($geo as $g) { if (is_string($g) && strlen($g) > 1) { $result[] = [ @@ -206,44 +206,44 @@ public function getContacts($myMapId=null): DataResponse { $card = $this->cdBackend->getContact($c['addressbook-key'], $c['URI']); if ($card) { $vcard = Reader::read($card['carddata']); - if (isset($vcard->ADR) && count($vcard->ADR) > 0) { - $prevGeo = []; - $prevRes = []; - foreach ($vcard->ADR as $adr) { - $geo = $this->addressService->addressToGeo($adr->getValue(), $c['URI']); - $geof = $this->geoAsFloatArray($geo); - $duplicatedIndex = $this->isNewAddress($prevGeo, $geof); - $adrtype = ''; - if (isset($adr->parameters()['TYPE'])) { - $adrtype = $adr->parameters()['TYPE']->getValue(); - } - if (is_string($geo) && strlen($geo) > 1) { - if ($duplicatedIndex < 0 ) { - array_push($prevGeo, $geof); - array_push($prevRes, count($result)); // Add index of new item so that we can update the ADRTYPE in case of duplicate address - $result[] = [ - 'FN' => $c['FN'] ?? $this->N2FN($c['N']) ?? '???', - 'URI' => $c['URI'], - 'UID' => $c['UID'], - 'URL' => $url, - 'ADR' => $adr->getValue(), - 'ADRTYPE' => array($adrtype), - 'HAS_PHOTO' => (isset($c['PHOTO']) && $c['PHOTO'] !== null), - 'BOOKID' => $c['addressbook-key'], - 'BOOKURI' => $addressBookUri, - 'GEO' => $geo, - 'GROUPS' => $c['CATEGORIES'] ?? null, - 'isDeletable' => true, - 'isUpdateable' => true, - ]; - } else { - // Concatenate AddressType to the corresponding record - array_push($result[$prevRes[$duplicatedIndex]]['ADRTYPE'], $adrtype); - $result[$prevRes[$duplicatedIndex]]['isUpdateable'] = false; - $result[$prevRes[$duplicatedIndex]]['isDeletable'] = false; - $result[$prevRes[$duplicatedIndex]]['isShareable'] = false; - } - } + if (isset($vcard->ADR) && count($vcard->ADR) > 0) { + $prevGeo = []; + $prevRes = []; + foreach ($vcard->ADR as $adr) { + $geo = $this->addressService->addressToGeo($adr->getValue(), $c['URI']); + $geof = $this->geoAsFloatArray($geo); + $duplicatedIndex = $this->isNewAddress($prevGeo, $geof); + $adrtype = ''; + if (isset($adr->parameters()['TYPE'])) { + $adrtype = $adr->parameters()['TYPE']->getValue(); + } + if (is_string($geo) && strlen($geo) > 1) { + if ($duplicatedIndex < 0) { + array_push($prevGeo, $geof); + array_push($prevRes, count($result)); // Add index of new item so that we can update the ADRTYPE in case of duplicate address + $result[] = [ + 'FN' => $c['FN'] ?? $this->N2FN($c['N']) ?? '???', + 'URI' => $c['URI'], + 'UID' => $c['UID'], + 'URL' => $url, + 'ADR' => $adr->getValue(), + 'ADRTYPE' => [$adrtype], + 'HAS_PHOTO' => (isset($c['PHOTO']) && $c['PHOTO'] !== null), + 'BOOKID' => $c['addressbook-key'], + 'BOOKURI' => $addressBookUri, + 'GEO' => $geo, + 'GROUPS' => $c['CATEGORIES'] ?? null, + 'isDeletable' => true, + 'isUpdateable' => true, + ]; + } else { + // Concatenate AddressType to the corresponding record + array_push($result[$prevRes[$duplicatedIndex]]['ADRTYPE'], $adrtype); + $result[$prevRes[$duplicatedIndex]]['isUpdateable'] = false; + $result[$prevRes[$duplicatedIndex]]['isDeletable'] = false; + $result[$prevRes[$duplicatedIndex]]['isShareable'] = false; + } + } } } } @@ -254,7 +254,7 @@ public function getContacts($myMapId=null): DataResponse { //Fixme add contacts for my-maps $result = []; $userFolder = $this->root->getUserFolder($this->userId); - $folders = $userFolder->getById($myMapId); + $folders = $userFolder->getById($myMapId); if (empty($folders)) { return new DataResponse($result); } @@ -264,7 +264,7 @@ public function getContacts($myMapId=null): DataResponse { } $files = $folder->search('.vcf'); foreach ($files as $file) { -// $cards = explode("END:VCARD\r\n", $file->getContent()); + // $cards = explode("END:VCARD\r\n", $file->getContent()); $cards = [$file->getContent()]; foreach ($cards as $card) { $vcard = Reader::read($card."END:VCARD\r\n"); @@ -272,43 +272,43 @@ public function getContacts($myMapId=null): DataResponse { $geo = $vcard->GEO; if (is_string($geo) && strlen($geo->getValue()) > 1) { $result[] = $this->vCardToArray($file, $vcard, $geo->getValue()); - } elseif (is_countable($geo) && count($geo)>0 && is_iterable($geo)) { - $prevGeo = ""; - foreach ($geo as $g) { - if (strcmp($prevGeo, $g->getValue()) != 0) { - $prevGeo = $g->getValue(); - if (strlen($g->getValue()) > 1) { - $result[] = $this->vCardToArray($file, $vcard, $g->getValue()); - } - } + } elseif (is_countable($geo) && count($geo) > 0 && is_iterable($geo)) { + $prevGeo = ''; + foreach ($geo as $g) { + if (strcmp($prevGeo, $g->getValue()) != 0) { + $prevGeo = $g->getValue(); + if (strlen($g->getValue()) > 1) { + $result[] = $this->vCardToArray($file, $vcard, $g->getValue()); + } + } } } } if (isset($vcard->ADR) && count($vcard->ADR) > 0) { - $prevGeo = []; - $prevRes = []; - foreach ($vcard->ADR as $adr) { + $prevGeo = []; + $prevRes = []; + foreach ($vcard->ADR as $adr) { $geo = $this->addressService->addressToGeo($adr->getValue(), $file->getId()); - $geof = $this->geoAsFloatArray($geo); - $duplicatedIndex = $this->isNewAddress($prevGeo, $geof); - //var_dump($adr->parameters()['TYPE']->getValue()); - $adrtype = ''; - if (isset($adr->parameters()['TYPE'])) { - $adrtype = $adr->parameters()['TYPE']->getValue(); - } - if (is_string($geo) && strlen($geo) > 1) { - if ($duplicatedIndex < 0 ) { - array_push($prevGeo, $geof); - array_push($prevRes, count($result)); // Add index of new item so that we can update the ADRTYPE in case of duplicate address - $result[] = $this->vCardToArray($file, $vcard, $geo, $adrtype, $adr->getValue(), $file->getId()); - } else { - // Concatenate AddressType to the corresponding record - array_push($result[$prevRes[$duplicatedIndex]]['ADRTYPE'], $adrtype); - $result[$prevRes[$duplicatedIndex]]['isUpdateable'] = false; - $result[$prevRes[$duplicatedIndex]]['isDeletable'] = false; - $result[$prevRes[$duplicatedIndex]]['isShareable'] = false; - } - } + $geof = $this->geoAsFloatArray($geo); + $duplicatedIndex = $this->isNewAddress($prevGeo, $geof); + //var_dump($adr->parameters()['TYPE']->getValue()); + $adrtype = ''; + if (isset($adr->parameters()['TYPE'])) { + $adrtype = $adr->parameters()['TYPE']->getValue(); + } + if (is_string($geo) && strlen($geo) > 1) { + if ($duplicatedIndex < 0) { + array_push($prevGeo, $geof); + array_push($prevRes, count($result)); // Add index of new item so that we can update the ADRTYPE in case of duplicate address + $result[] = $this->vCardToArray($file, $vcard, $geo, $adrtype, $adr->getValue(), $file->getId()); + } else { + // Concatenate AddressType to the corresponding record + array_push($result[$prevRes[$duplicatedIndex]]['ADRTYPE'], $adrtype); + $result[$prevRes[$duplicatedIndex]]['isUpdateable'] = false; + $result[$prevRes[$duplicatedIndex]]['isDeletable'] = false; + $result[$prevRes[$duplicatedIndex]]['isShareable'] = false; + } + } } } } @@ -341,7 +341,7 @@ private function directUrlToContact($contactUid, $addressBookUri) { * @throws NotFoundException * @throws \OCP\Files\InvalidPathException */ - private function vCardToArray(Node $file, \Sabre\VObject\Document $vcard, string $geo, ?string $adrtype=null, ?string $adr=null, ?int $fileId = null): array { + private function vCardToArray(Node $file, \Sabre\VObject\Document $vcard, string $geo, ?string $adrtype = null, ?string $adr = null, ?int $fileId = null): array { $FNArray = $vcard->FN ? $vcard->FN->getJsonValue() : []; $fn = array_shift($FNArray); $NArray = $vcard->N ? $vcard->N->getJsonValue() : []; @@ -387,12 +387,10 @@ private function N2FN(string $n): ?string { $spl = explode($n, ';'); if (count($spl) >= 4) { return $spl[3] . ' ' . $spl[1] . ' ' . $spl[0]; - } - else { + } else { return null; } - } - else { + } else { return null; } } @@ -405,7 +403,7 @@ private function N2FN(string $n): ?string { * @return DataResponse */ public function searchContacts(string $query = ''): DataResponse { - $contacts = $this->contactsManager->search($query, ['FN'], ['types'=>false]); + $contacts = $this->contactsManager->search($query, ['FN'], ['types' => false]); $booksReadOnly = $this->getAddressBooksReadOnly(); $addressBooks = $this->contactsManager->getUserAddressBooks(); $result = []; @@ -461,17 +459,17 @@ public function placeContact( string $uid, ?float $lat, ?float $lng, - string $attraction='', - string $house_number='', - string $road='', - string $postcode='', - string $city='', - string $state='', - string $country='', - string $type='', - ?string $address_string=null, - ?int $fileId=null, - ?int $myMapId=null): DataResponse { + string $attraction = '', + string $house_number = '', + string $road = '', + string $postcode = '', + string $city = '', + string $state = '', + string $country = '', + string $type = '', + ?string $address_string = null, + ?int $fileId = null, + ?int $myMapId = null): DataResponse { if (is_null($myMapId) || $myMapId === '') { // do not edit 'user' contact even myself if (strcmp($uri, 'Database:'.$uid.'.vcf') === 0 or @@ -484,7 +482,7 @@ public function placeContact( if ($lat !== null && $lng !== null) { // we set the geo tag if (!$attraction && !$house_number && !$road && !$postcode && !$city && !$state && !$country && !$address_string) { - $result = $this->contactsManager->createOrUpdate(['URI'=>$uri, 'GEO'=>$lat.';'.$lng], $bookid); + $result = $this->contactsManager->createOrUpdate(['URI' => $uri, 'GEO' => $lat.';'.$lng], $bookid); } // we set the address elseif (!$address_string) { @@ -497,49 +495,49 @@ public function placeContact( // set the address in the vcard $card = $this->cdBackend->getContact($bookid, $uri); if ($card) { - $vcard = Reader::read($card['carddata']);; - $vcard->add(new Text($vcard, 'ADR', ['', '', $street, $city, $state, $postcode, $country], ['TYPE'=>$type])); + $vcard = Reader::read($card['carddata']); + ; + $vcard->add(new Text($vcard, 'ADR', ['', '', $street, $city, $state, $postcode, $country], ['TYPE' => $type])); $result = $this->cdBackend->updateCard($bookid, $uri, $vcard->serialize()); } } else { $card = $this->cdBackend->getContact($bookid, $uri); if ($card) { - $vcard = Reader::read($card['carddata']);; - $vcard->add(new Text($vcard, 'ADR', explode(';',$address_string), ['TYPE'=>$type])); + $vcard = Reader::read($card['carddata']); + ; + $vcard->add(new Text($vcard, 'ADR', explode(';', $address_string), ['TYPE' => $type])); $result = $this->cdBackend->updateCard($bookid, $uri, $vcard->serialize()); } } - } - else { + } else { // TODO find out how to remove a property // following does not work properly - $result = $this->contactsManager->createOrUpdate(['URI'=>$uri, 'GEO'=>null], $bookid); + $result = $this->contactsManager->createOrUpdate(['URI' => $uri, 'GEO' => null], $bookid); } return new DataResponse('EDITED'); - } - else { + } else { return new DataResponse('READONLY', 400); } } } else { $userFolder = $this->root->getUserFolder($this->userId); - $folders = $userFolder->getById($myMapId); + $folders = $userFolder->getById($myMapId); if (empty($folders)) { return new DataResponse('MAP NOT FOUND', 404); } $mapsFolder = array_shift($folders); if (is_null($mapsFolder)) { - return new DataResponse('MAP NOT FOUND',404); + return new DataResponse('MAP NOT FOUND', 404); } if (is_null($fileId)) { $card = $this->cdBackend->getContact($bookid, $uri); try { - $file=$mapsFolder->get($uri); + $file = $mapsFolder->get($uri); } catch (NotFoundException $e) { if (!$mapsFolder->isCreatable()) { return new DataResponse('CONTACT NOT WRITABLE', 400); } - $file=$mapsFolder->newFile($uri); + $file = $mapsFolder->newFile($uri); } } else { $files = $mapsFolder->getById($fileId); @@ -559,7 +557,7 @@ public function placeContact( $vcard = Reader::read($card['carddata']); if ($lat !== null && $lng !== null) { if (!$attraction && !$house_number && !$road && !$postcode && !$city && !$state && !$country && !$address_string) { - $vcard->add('GEO',$lat.';'.$lng); + $vcard->add('GEO', $lat.';'.$lng); } elseif (!$address_string) { $street = trim($attraction.' '.$house_number.' '.$road); $stringAddress = ';;'.$street.';'.$city.';'.$state.';'.$postcode.';'.$country; @@ -568,7 +566,7 @@ public function placeContact( $lng = floatval($lng); $this->setAddressCoordinates($lat, $lng, $stringAddress, $uri); $vcard = Reader::read($card['carddata']); - $vcard->add( 'ADR', ['', '', $street, $city, $state, $postcode, $country], ['TYPE'=>$type]); + $vcard->add('ADR', ['', '', $street, $city, $state, $postcode, $country], ['TYPE' => $type]); } else { $stringAddress = $address_string; // set the coordinates in the DB @@ -576,7 +574,7 @@ public function placeContact( $lng = floatval($lng); $this->setAddressCoordinates($lat, $lng, $stringAddress, $uri); $vcard = Reader::read($card['carddata']); - $vcard->add( 'ADR', explode(';',$address_string), ['TYPE'=>$type]); + $vcard->add('ADR', explode(';', $address_string), ['TYPE' => $type]); } } else { $vcard->remove('GEO'); @@ -599,25 +597,25 @@ public function placeContact( * @throws \OCP\Files\NotPermittedException * @throws \OC\User\NoUserException */ - public function addContactToMap(string $bookid, string $uri, int $myMapId, ?int $fileId=null): DataResponse { + public function addContactToMap(string $bookid, string $uri, int $myMapId, ?int $fileId = null): DataResponse { $userFolder = $this->root->getUserFolder($this->userId); - $folders = $userFolder->getById($myMapId); + $folders = $userFolder->getById($myMapId); if (empty($folders)) { return new DataResponse('MAP NOT FOUND', 404); } $mapsFolder = array_shift($folders); if (is_null($mapsFolder)) { - return new DataResponse('MAP NOT FOUND',404); + return new DataResponse('MAP NOT FOUND', 404); } if (is_null($fileId)) { $card = $this->cdBackend->getContact($bookid, $uri); try { - $file=$mapsFolder->get($uri); + $file = $mapsFolder->get($uri); } catch (NotFoundException $e) { if (!$mapsFolder->isCreatable()) { return new DataResponse('CONTACT NOT WRITABLE', 400); } - $file=$mapsFolder->newFile($uri); + $file = $mapsFolder->newFile($uri); } } else { $files = $mapsFolder->getById($fileId); @@ -697,21 +695,20 @@ private function setAddressCoordinates(float $lat, float $lng, string $adr, stri ->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_STR))); $req = $qb->execute(); - } - else { + } else { $qb->insert('maps_address_geo') ->values([ - 'adr'=>$qb->createNamedParameter($adr, IQueryBuilder::PARAM_STR), - 'adr_norm'=>$qb->createNamedParameter($adr_norm, IQueryBuilder::PARAM_STR), - 'object_uri'=>$qb->createNamedParameter($uri, IQueryBuilder::PARAM_STR), - 'lat'=>$qb->createNamedParameter($lat, IQueryBuilder::PARAM_STR), - 'lng'=>$qb->createNamedParameter($lng, IQueryBuilder::PARAM_STR), - 'looked_up'=>$qb->createNamedParameter(true, IQueryBuilder::PARAM_BOOL), + 'adr' => $qb->createNamedParameter($adr, IQueryBuilder::PARAM_STR), + 'adr_norm' => $qb->createNamedParameter($adr_norm, IQueryBuilder::PARAM_STR), + 'object_uri' => $qb->createNamedParameter($uri, IQueryBuilder::PARAM_STR), + 'lat' => $qb->createNamedParameter($lat, IQueryBuilder::PARAM_STR), + 'lng' => $qb->createNamedParameter($lng, IQueryBuilder::PARAM_STR), + 'looked_up' => $qb->createNamedParameter(true, IQueryBuilder::PARAM_BOOL), ]); $req = $qb->execute(); $id = $qb->getLastInsertId(); - }$qb = $qb->resetQueryParts(); - } + }$qb = $qb->resetQueryParts(); + } /** @@ -744,7 +741,7 @@ public function getContactLetterAvatar(string $name): DataDisplayResponse { * @param ?int $myMapId * @return DataResponse */ - public function deleteContactAddress($bookid, $uri, $uid, $adr, $geo, $fileId=null, $myMapId=null): DataResponse { + public function deleteContactAddress($bookid, $uri, $uid, $adr, $geo, $fileId = null, $myMapId = null): DataResponse { // vcard $card = $this->cdBackend->getContact($bookid, $uri); @@ -770,12 +767,10 @@ public function deleteContactAddress($bookid, $uri, $uid, $adr, $geo, $fileId=nu $this->cdBackend->updateCard($bookid, $uri, $vcard->serialize()); // no need to cleanup db here, it will be done when catching vcard change hook return new DataResponse('DELETED'); - } - else { + } else { return new DataResponse('READONLY', 400); } - } - else { + } else { return new DataResponse('FAILED', 400); } } diff --git a/lib/Controller/DevicesApiController.php b/lib/Controller/DevicesApiController.php index e64b444be..6c122abee 100644 --- a/lib/Controller/DevicesApiController.php +++ b/lib/Controller/DevicesApiController.php @@ -11,82 +11,75 @@ namespace OCA\Maps\Controller; -use OCP\App\IAppManager; +use OCA\Maps\Service\DevicesService; -use OCP\IURLGenerator; -use OCP\IConfig; -use \OCP\IL10N; +use OCP\App\IAppManager; +use OCP\AppFramework\ApiController; use OCP\AppFramework\Http; -use OCP\AppFramework\Http\RedirectResponse; -use OCP\AppFramework\Http\ContentSecurityPolicy; -use OCP\IRequest; -use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Http\DataResponse; -use OCP\AppFramework\Controller; -use OCP\AppFramework\ApiController; -use OCP\Constants; -use OCP\Share; -use OCP\IUserManager; -use OCP\Share\IManager; -use OCP\IServerContainer; +use OCP\IConfig; use OCP\IGroupManager; +use OCP\IL10N; use OCP\ILogger; +use OCP\IRequest; +use OCP\IServerContainer; +use OCP\IUserManager; -use OCA\Maps\Service\DevicesService; +use OCP\Share\IManager; class DevicesApiController extends ApiController { - private $userId; - private $userfolder; - private $config; - private $appVersion; - private $shareManager; - private $userManager; - private $groupManager; - private $dbtype; - private $dbdblquotes; - private $defaultDeviceId; - private $l; - private $logger; - private $devicesService; - protected $appName; - - public function __construct($AppName, - IRequest $request, - IServerContainer $serverContainer, - IConfig $config, - IManager $shareManager, - IAppManager $appManager, - IUserManager $userManager, - IGroupManager $groupManager, - IL10N $l, - ILogger $logger, - DevicesService $devicesService, - $UserId){ - parent::__construct($AppName, $request, - 'PUT, POST, GET, DELETE, PATCH, OPTIONS', - 'Authorization, Content-Type, Accept', - 1728000); - $this->devicesService = $devicesService; - $this->logger = $logger; - $this->appName = $AppName; - $this->appVersion = $config->getAppValue('maps', 'installed_version'); - $this->userId = $UserId; - $this->userManager = $userManager; - $this->groupManager = $groupManager; - $this->l = $l; - $this->dbtype = $config->getSystemValue('dbtype'); - // IConfig object - $this->config = $config; - if ($UserId !== '' and $UserId !== null and $serverContainer !== null){ - // path of user files folder relative to DATA folder - $this->userfolder = $serverContainer->getUserFolder($UserId); - } - $this->shareManager = $shareManager; - } + private $userId; + private $userfolder; + private $config; + private $appVersion; + private $shareManager; + private $userManager; + private $groupManager; + private $dbtype; + private $dbdblquotes; + private $defaultDeviceId; + private $l; + private $logger; + private $devicesService; + protected $appName; + + public function __construct($AppName, + IRequest $request, + IServerContainer $serverContainer, + IConfig $config, + IManager $shareManager, + IAppManager $appManager, + IUserManager $userManager, + IGroupManager $groupManager, + IL10N $l, + ILogger $logger, + DevicesService $devicesService, + $UserId) { + parent::__construct($AppName, $request, + 'PUT, POST, GET, DELETE, PATCH, OPTIONS', + 'Authorization, Content-Type, Accept', + 1728000); + $this->devicesService = $devicesService; + $this->logger = $logger; + $this->appName = $AppName; + $this->appVersion = $config->getAppValue('maps', 'installed_version'); + $this->userId = $UserId; + $this->userManager = $userManager; + $this->groupManager = $groupManager; + $this->l = $l; + $this->dbtype = $config->getSystemValue('dbtype'); + // IConfig object + $this->config = $config; + if ($UserId !== '' and $UserId !== null and $serverContainer !== null) { + // path of user files folder relative to DATA folder + $this->userfolder = $serverContainer->getUserFolder($UserId); + } + $this->shareManager = $shareManager; + } /** * @NoAdminRequired @@ -95,19 +88,19 @@ public function __construct($AppName, * @param $apiversion * @return DataResponse */ - public function getDevices($apiversion): DataResponse { - $now = new \DateTime(); + public function getDevices($apiversion): DataResponse { + $now = new \DateTime(); - $devices = $this->devicesService->getDevicesFromDB($this->userId); + $devices = $this->devicesService->getDevicesFromDB($this->userId); - $etag = md5(json_encode($devices)); - if ($this->request->getHeader('If-None-Match') === '"'.$etag.'"') { - return new DataResponse([], Http::STATUS_NOT_MODIFIED); - } - return (new DataResponse($devices)) - ->setLastModified($now) - ->setETag($etag); - } + $etag = md5(json_encode($devices)); + if ($this->request->getHeader('If-None-Match') === '"'.$etag.'"') { + return new DataResponse([], Http::STATUS_NOT_MODIFIED); + } + return (new DataResponse($devices)) + ->setLastModified($now) + ->setETag($etag); + } /** * @NoAdminRequired @@ -117,10 +110,10 @@ public function getDevices($apiversion): DataResponse { * @param int $pruneBefore * @return DataResponse */ - public function getDevicePoints($id, int $pruneBefore=0): DataResponse { - $points = $this->devicesService->getDevicePointsFromDB($this->userId, $id, $pruneBefore); - return new DataResponse($points); - } + public function getDevicePoints($id, int $pruneBefore = 0): DataResponse { + $points = $this->devicesService->getDevicePointsFromDB($this->userId, $id, $pruneBefore); + return new DataResponse($points); + } /** * @NoAdminRequired @@ -136,31 +129,30 @@ public function getDevicePoints($id, int $pruneBefore=0): DataResponse { * @param $accuracy * @return DataResponse */ - public function addDevicePoint($apiversion, $lat, $lng, $timestamp=null, $user_agent=null, $altitude=null, $battery=null, $accuracy=null): DataResponse { - if (is_numeric($lat) and is_numeric($lng)) { - $timestamp = $this->normalizeOptionalNumber($timestamp); - $altitude = $this->normalizeOptionalNumber($altitude); - $battery = $this->normalizeOptionalNumber($battery); - $accuracy = $this->normalizeOptionalNumber($accuracy); - $ts = $timestamp; - if ($timestamp === null) { - $ts = (new \DateTime())->getTimestamp(); - } - $ua = $user_agent; - if ($user_agent === null) { - $ua = $_SERVER['HTTP_USER_AGENT']; - } - $deviceId = $this->devicesService->getOrCreateDeviceFromDB($this->userId, $ua); - $pointId = $this->devicesService->addPointToDB($deviceId, $lat, $lng, $ts, $altitude, $battery, $accuracy); - return new DataResponse([ - 'deviceId'=>$deviceId, - 'pointId'=>$pointId - ]); - } - else { - return new DataResponse($this->l->t('Invalid values'), 400); - } - } + public function addDevicePoint($apiversion, $lat, $lng, $timestamp = null, $user_agent = null, $altitude = null, $battery = null, $accuracy = null): DataResponse { + if (is_numeric($lat) and is_numeric($lng)) { + $timestamp = $this->normalizeOptionalNumber($timestamp); + $altitude = $this->normalizeOptionalNumber($altitude); + $battery = $this->normalizeOptionalNumber($battery); + $accuracy = $this->normalizeOptionalNumber($accuracy); + $ts = $timestamp; + if ($timestamp === null) { + $ts = (new \DateTime())->getTimestamp(); + } + $ua = $user_agent; + if ($user_agent === null) { + $ua = $_SERVER['HTTP_USER_AGENT']; + } + $deviceId = $this->devicesService->getOrCreateDeviceFromDB($this->userId, $ua); + $pointId = $this->devicesService->addPointToDB($deviceId, $lat, $lng, $ts, $altitude, $battery, $accuracy); + return new DataResponse([ + 'deviceId' => $deviceId, + 'pointId' => $pointId + ]); + } else { + return new DataResponse($this->l->t('Invalid values'), 400); + } + } /** * @NoAdminRequired @@ -170,22 +162,20 @@ public function addDevicePoint($apiversion, $lat, $lng, $timestamp=null, $user_a * @param $color * @return DataResponse */ - public function editDevice($id, $color): DataResponse { - $device = $this->devicesService->getDeviceFromDB($id, $this->userId); - if ($device !== null) { - if (is_string($color) && strlen($color) > 0) { - $this->devicesService->editDeviceInDB($id, $color, null); - $editedDevice = $this->devicesService->getDeviceFromDB($id, $this->userId); - return new DataResponse($editedDevice); - } - else { - return new DataResponse($this->l->t('Invalid values'), 400); - } - } - else { - return new DataResponse($this->l->t('No such device'), 400); - } - } + public function editDevice($id, $color): DataResponse { + $device = $this->devicesService->getDeviceFromDB($id, $this->userId); + if ($device !== null) { + if (is_string($color) && strlen($color) > 0) { + $this->devicesService->editDeviceInDB($id, $color, null); + $editedDevice = $this->devicesService->getDeviceFromDB($id, $this->userId); + return new DataResponse($editedDevice); + } else { + return new DataResponse($this->l->t('Invalid values'), 400); + } + } else { + return new DataResponse($this->l->t('No such device'), 400); + } + } /** * @NoAdminRequired @@ -194,26 +184,25 @@ public function editDevice($id, $color): DataResponse { * @param $id * @return DataResponse */ - public function deleteDevice($id): DataResponse { - $device = $this->devicesService->getDeviceFromDB($id, $this->userId); - if ($device !== null) { - $this->devicesService->deleteDeviceFromDB($id); - return new DataResponse('DELETED'); - } - else { - return new DataResponse($this->l->t('No such device'), 400); - } - } + public function deleteDevice($id): DataResponse { + $device = $this->devicesService->getDeviceFromDB($id, $this->userId); + if ($device !== null) { + $this->devicesService->deleteDeviceFromDB($id); + return new DataResponse('DELETED'); + } else { + return new DataResponse($this->l->t('No such device'), 400); + } + } /** * @param $value * @return float|int|string|null */ - private function normalizeOptionalNumber($value) { - if (!is_numeric($value)) { - return null; - } - return $value; - } + private function normalizeOptionalNumber($value) { + if (!is_numeric($value)) { + return null; + } + return $value; + } } diff --git a/lib/Controller/DevicesController.php b/lib/Controller/DevicesController.php index cb1d81646..05fcbe8d8 100644 --- a/lib/Controller/DevicesController.php +++ b/lib/Controller/DevicesController.php @@ -13,95 +13,88 @@ use OCA\Files_External\NotFoundException; use OCA\Maps\DB\DeviceShareMapper; -use OCP\App\IAppManager; +use OCA\Maps\Service\DevicesService; +use OCP\App\IAppManager; +use OCP\AppFramework\Controller; use OCP\AppFramework\Db\DoesNotExistException; -use OCP\Files\IRootFolder; -use OCP\Files\NotPermittedException; -use OCP\IURLGenerator; -use OCP\IConfig; -use \OCP\IL10N; - use OCP\AppFramework\Http; -use OCP\AppFramework\Http\RedirectResponse; +use OCP\AppFramework\Http\DataResponse; -use OCP\AppFramework\Http\ContentSecurityPolicy; +use OCP\Files\IRootFolder; -use OCP\IRequest; -use OCP\AppFramework\Http\TemplateResponse; -use OCP\AppFramework\Http\DataResponse; -use OCP\AppFramework\Controller; -use OCP\AppFramework\ApiController; -use OCP\Constants; -use OCP\Share; -use OCP\IUserManager; -use OCP\Share\IManager; -use OCP\IServerContainer; + +use OCP\Files\NotPermittedException; +use OCP\IConfig; +use OCP\IDateTimeZone; use OCP\IGroupManager; +use OCP\IL10N; use OCP\ILogger; +use OCP\IRequest; +use OCP\IServerContainer; -use OCP\IDateTimeZone; +use OCP\IUserManager; -use OCA\Maps\Service\DevicesService; +use OCP\Share\IManager; //use function \OCA\Maps\Service\endswith; class DevicesController extends Controller { - private $userId; - private $userfolder; - private $config; - private $appVersion; - private $shareManager; - private $userManager; - private $groupManager; - private $dbtype; - private $dbdblquotes; - private $defaultDeviceId; - private $l; - private $logger; - private $devicesService; + private $userId; + private $userfolder; + private $config; + private $appVersion; + private $shareManager; + private $userManager; + private $groupManager; + private $dbtype; + private $dbdblquotes; + private $defaultDeviceId; + private $l; + private $logger; + private $devicesService; private $deviceShareMapper; - private $dateTimeZone; + private $dateTimeZone; private $root; - protected $appName; - - public function __construct($AppName, - IRequest $request, - IServerContainer $serverContainer, - IConfig $config, - IManager $shareManager, - IAppManager $appManager, - IUserManager $userManager, - IGroupManager $groupManager, - IL10N $l, - ILogger $logger, - DevicesService $devicesService, - DeviceShareMapper $deviceShareMapper, - IDateTimeZone $dateTimeZone, - IRootFolder $root, - $UserId){ - parent::__construct($AppName, $request); - $this->devicesService = $devicesService; + protected $appName; + + public function __construct($AppName, + IRequest $request, + IServerContainer $serverContainer, + IConfig $config, + IManager $shareManager, + IAppManager $appManager, + IUserManager $userManager, + IGroupManager $groupManager, + IL10N $l, + ILogger $logger, + DevicesService $devicesService, + DeviceShareMapper $deviceShareMapper, + IDateTimeZone $dateTimeZone, + IRootFolder $root, + $UserId) { + parent::__construct($AppName, $request); + $this->devicesService = $devicesService; $this->deviceShareMapper = $deviceShareMapper; - $this->dateTimeZone = $dateTimeZone; - $this->logger = $logger; - $this->appName = $AppName; - $this->appVersion = $config->getAppValue('maps', 'installed_version'); - $this->userId = $UserId; - $this->userManager = $userManager; - $this->groupManager = $groupManager; - $this->l = $l; + $this->dateTimeZone = $dateTimeZone; + $this->logger = $logger; + $this->appName = $AppName; + $this->appVersion = $config->getAppValue('maps', 'installed_version'); + $this->userId = $UserId; + $this->userManager = $userManager; + $this->groupManager = $groupManager; + $this->l = $l; $this->root = $root; - $this->dbtype = $config->getSystemValue('dbtype'); - // IConfig object - $this->config = $config; - if ($UserId !== '' and $UserId !== null and $serverContainer !== null){ - // path of user files folder relative to DATA folder - $this->userfolder = $serverContainer->getUserFolder($UserId); - } - $this->shareManager = $shareManager; - } + $this->dbtype = $config->getSystemValue('dbtype'); + // IConfig object + $this->config = $config; + if ($UserId !== '' and $UserId !== null and $serverContainer !== null) { + // path of user files folder relative to DATA folder + $this->userfolder = $serverContainer->getUserFolder($UserId); + } + $this->shareManager = $shareManager; + } /** * @NoAdminRequired @@ -109,9 +102,9 @@ public function __construct($AppName, * @param ?int $myMapId * @return DataResponse */ - public function getDevices($tokens=null, $myMapId=null): DataResponse { + public function getDevices($tokens = null, $myMapId = null): DataResponse { if (is_null($tokens)) { - $tokens = array(); + $tokens = []; } if (is_null($myMapId)) { $devices = $this->devicesService->getDevicesFromDB($this->userId); @@ -125,7 +118,7 @@ public function getDevices($tokens=null, $myMapId=null): DataResponse { $userFolder = $this->root->getUserFolder($this->userId); $folders = $userFolder->getById($myMapId); $folder = array_shift($folders); - if(is_null($folder)) { + if (is_null($folder)) { return new DataResponse($this->l->t('Map not Found'), 404); } $shares = $this->devicesService->getSharedDevicesFromFolder($folder); @@ -134,8 +127,8 @@ public function getDevices($tokens=null, $myMapId=null): DataResponse { } $td = $this->devicesService->getDevicesByTokens($tokens); $devices = $td + $devices; - return new DataResponse(array_values($devices)); - } + return new DataResponse(array_values($devices)); + } /** * @NoAdminRequired @@ -153,14 +146,14 @@ public function getDevicesByTokens(array $tokens): DataResponse { * @param int $pruneBefore * @return DataResponse */ - public function getDevicePoints($id, ?int $pruneBefore=0, ?int $limit=10000, ?int $offset=0, ?array $tokens=null): DataResponse { + public function getDevicePoints($id, ?int $pruneBefore = 0, ?int $limit = 10000, ?int $offset = 0, ?array $tokens = null): DataResponse { if (is_null($tokens)) { $points = $this->devicesService->getDevicePointsFromDB($this->userId, $id, $pruneBefore, $limit, $offset); } else { $points = $this->devicesService->getDevicePointsByTokens($tokens, $pruneBefore, $limit, $offset); } - return new DataResponse($points); - } + return new DataResponse($points); + } /** * @NoAdminRequired @@ -173,27 +166,26 @@ public function getDevicePoints($id, ?int $pruneBefore=0, ?int $limit=10000, ?in * @param null $accuracy * @return DataResponse */ - public function addDevicePoint($lat, $lng, $timestamp=null, $user_agent=null, $altitude=null, $battery=null, $accuracy=null): DataResponse { - if (is_numeric($lat) and is_numeric($lng)) { - $ts = $timestamp; - if ($timestamp === null) { - $ts = (new \DateTime())->getTimestamp(); - } - $ua = $user_agent; - if ($user_agent === null) { - $ua = $_SERVER['HTTP_USER_AGENT']; - } - $deviceId = $this->devicesService->getOrCreateDeviceFromDB($this->userId, $ua); - $pointId = $this->devicesService->addPointToDB($deviceId, $lat, $lng, $ts, $altitude, $battery, $accuracy); - return new DataResponse([ - 'deviceId'=>$deviceId, - 'pointId'=>$pointId - ]); - } - else { - return new DataResponse('Invalid values', 400); - } - } + public function addDevicePoint($lat, $lng, $timestamp = null, $user_agent = null, $altitude = null, $battery = null, $accuracy = null): DataResponse { + if (is_numeric($lat) and is_numeric($lng)) { + $ts = $timestamp; + if ($timestamp === null) { + $ts = (new \DateTime())->getTimestamp(); + } + $ua = $user_agent; + if ($user_agent === null) { + $ua = $_SERVER['HTTP_USER_AGENT']; + } + $deviceId = $this->devicesService->getOrCreateDeviceFromDB($this->userId, $ua); + $pointId = $this->devicesService->addPointToDB($deviceId, $lat, $lng, $ts, $altitude, $battery, $accuracy); + return new DataResponse([ + 'deviceId' => $deviceId, + 'pointId' => $pointId + ]); + } else { + return new DataResponse('Invalid values', 400); + } + } /** * @NoAdminRequired @@ -202,41 +194,38 @@ public function addDevicePoint($lat, $lng, $timestamp=null, $user_agent=null, $a * @param $name * @return DataResponse */ - public function editDevice($id, $color, $name): DataResponse { - $device = $this->devicesService->getDeviceFromDB($id, $this->userId); - if ($device !== null) { - if ((is_string($color) && strlen($color) > 0) || - (is_string($name) && strlen($name) > 0) - ) { - $this->devicesService->editDeviceInDB($id, $color, $name); - $editedDevice = $this->devicesService->getDeviceFromDB($id, $this->userId); - return new DataResponse($editedDevice); - } - else { - return new DataResponse($this->l->t('Invalid values'), 400); - } - } - else { - return new DataResponse($this->l->t('No such device'), 400); - } - } + public function editDevice($id, $color, $name): DataResponse { + $device = $this->devicesService->getDeviceFromDB($id, $this->userId); + if ($device !== null) { + if ((is_string($color) && strlen($color) > 0) || + (is_string($name) && strlen($name) > 0) + ) { + $this->devicesService->editDeviceInDB($id, $color, $name); + $editedDevice = $this->devicesService->getDeviceFromDB($id, $this->userId); + return new DataResponse($editedDevice); + } else { + return new DataResponse($this->l->t('Invalid values'), 400); + } + } else { + return new DataResponse($this->l->t('No such device'), 400); + } + } /** * @NoAdminRequired * @param $id * @return DataResponse */ - public function deleteDevice($id): DataResponse { - $device = $this->devicesService->getDeviceFromDB($id, $this->userId); - if ($device !== null) { - $this->devicesService->deleteDeviceFromDB($id); + public function deleteDevice($id): DataResponse { + $device = $this->devicesService->getDeviceFromDB($id, $this->userId); + if ($device !== null) { + $this->devicesService->deleteDeviceFromDB($id); $this->deviceShareMapper->removeAllByDeviceId($id); - return new DataResponse('DELETED'); - } - else { - return new DataResponse($this->l->t('No such device'), 400); - } - } + return new DataResponse('DELETED'); + } else { + return new DataResponse($this->l->t('No such device'), 400); + } + } /** * @NoAdminRequired @@ -248,55 +237,53 @@ public function deleteDevice($id): DataResponse { * @throws \OCP\Files\NotFoundException * @throws \OCP\Files\NotPermittedException */ - public function exportDevices($deviceIdList, $begin, $end, bool $all=false): DataResponse { - // sorry about ugly deviceIdList management: - // when an empty list is passed in http request, we get null here - if ($deviceIdList === null or (is_array($deviceIdList) and count($deviceIdList) === 0)) { - return new DataResponse($this->l->t('No device to export'), 400); - } - - // create /Maps directory if necessary - $userFolder = $this->userfolder; - if (!$userFolder->nodeExists('/Maps')) { - $userFolder->newFolder('Maps'); - } - if ($userFolder->nodeExists('/Maps')) { - $mapsFolder = $userFolder->get('/Maps'); - if ($mapsFolder->getType() !== \OCP\Files\FileInfo::TYPE_FOLDER) { - return new DataResponse($this->l->t('/Maps is not a directory'), 400); - } - else if (!$mapsFolder->isCreatable()) { - return new DataResponse($this->l->t('/Maps directory is not writeable'), 400); - } - } - else { - return new DataResponse($this->l->t('Impossible to create /Maps directory'), 400); - } - - $nbDevices = $this->devicesService->countPoints($this->userId, $deviceIdList, $begin, $end); - if ($nbDevices === 0) { - return new DataResponse($this->l->t('Nothing to export'), 400); - } - - // generate export file name - $prefix = $all ? '' : 'filtered-'; - $tz = $this->dateTimeZone->getTimeZone(); - $now = new \DateTime('now', $tz); - $dateStr = $now->format('Y-m-d H:i:s (P)'); - $filename = $dateStr.' '.$prefix.'devices.gpx'; - - if ($mapsFolder->nodeExists($filename)) { - $mapsFolder->get($filename)->delete(); - } - $file = $mapsFolder->newFile($filename); - $handler = $file->fopen('w'); - - $this->devicesService->exportDevices($this->userId, $handler, $deviceIdList, $begin, $end, $this->appVersion, $filename); - - fclose($handler); - $file->touch(); - return new DataResponse('/Maps/'.$filename); - } + public function exportDevices($deviceIdList, $begin, $end, bool $all = false): DataResponse { + // sorry about ugly deviceIdList management: + // when an empty list is passed in http request, we get null here + if ($deviceIdList === null or (is_array($deviceIdList) and count($deviceIdList) === 0)) { + return new DataResponse($this->l->t('No device to export'), 400); + } + + // create /Maps directory if necessary + $userFolder = $this->userfolder; + if (!$userFolder->nodeExists('/Maps')) { + $userFolder->newFolder('Maps'); + } + if ($userFolder->nodeExists('/Maps')) { + $mapsFolder = $userFolder->get('/Maps'); + if ($mapsFolder->getType() !== \OCP\Files\FileInfo::TYPE_FOLDER) { + return new DataResponse($this->l->t('/Maps is not a directory'), 400); + } elseif (!$mapsFolder->isCreatable()) { + return new DataResponse($this->l->t('/Maps directory is not writeable'), 400); + } + } else { + return new DataResponse($this->l->t('Impossible to create /Maps directory'), 400); + } + + $nbDevices = $this->devicesService->countPoints($this->userId, $deviceIdList, $begin, $end); + if ($nbDevices === 0) { + return new DataResponse($this->l->t('Nothing to export'), 400); + } + + // generate export file name + $prefix = $all ? '' : 'filtered-'; + $tz = $this->dateTimeZone->getTimeZone(); + $now = new \DateTime('now', $tz); + $dateStr = $now->format('Y-m-d H:i:s (P)'); + $filename = $dateStr.' '.$prefix.'devices.gpx'; + + if ($mapsFolder->nodeExists($filename)) { + $mapsFolder->get($filename)->delete(); + } + $file = $mapsFolder->newFile($filename); + $handler = $file->fopen('w'); + + $this->devicesService->exportDevices($this->userId, $handler, $deviceIdList, $begin, $end, $this->appVersion, $filename); + + fclose($handler); + $file->touch(); + return new DataResponse('/Maps/'.$filename); + } /** * @NoAdminRequired @@ -305,46 +292,45 @@ public function exportDevices($deviceIdList, $begin, $end, bool $all=false): Dat * @throws \OCP\Files\InvalidPathException * @throws \OCP\Files\NotFoundException */ - public function importDevices($path): DataResponse { - $userFolder = $this->userfolder; - $cleanpath = str_replace(array('../', '..\\'), '', $path); - - if ($userFolder->nodeExists($cleanpath)){ - $file = $userFolder->get($cleanpath); - if ($file->getType() === \OCP\Files\FileInfo::TYPE_FILE and - $file->isReadable()){ - $lowerFileName = strtolower($file->getName()); - if ($this->endsWith($lowerFileName, '.gpx') or $this->endsWith($lowerFileName, '.kml') or $this->endsWith($lowerFileName, '.kmz')) { - $nbImported = $this->devicesService->importDevices($this->userId, $file); - return new DataResponse($nbImported); - } - else { - // invalid extension - return new DataResponse($this->l->t('Invalid file extension'), 400); - } - } - else { - // directory or not readable - return new DataResponse($this->l->t('Impossible to read the file'), 400); - } - } - else { - // does not exist - return new DataResponse($this->l->t('File does not exist'), 400); - } - } + public function importDevices($path): DataResponse { + $userFolder = $this->userfolder; + $cleanpath = str_replace(['../', '..\\'], '', $path); + + if ($userFolder->nodeExists($cleanpath)) { + $file = $userFolder->get($cleanpath); + if ($file->getType() === \OCP\Files\FileInfo::TYPE_FILE and + $file->isReadable()) { + $lowerFileName = strtolower($file->getName()); + if ($this->endsWith($lowerFileName, '.gpx') or $this->endsWith($lowerFileName, '.kml') or $this->endsWith($lowerFileName, '.kmz')) { + $nbImported = $this->devicesService->importDevices($this->userId, $file); + return new DataResponse($nbImported); + } else { + // invalid extension + return new DataResponse($this->l->t('Invalid file extension'), 400); + } + } else { + // directory or not readable + return new DataResponse($this->l->t('Impossible to read the file'), 400); + } + } else { + // does not exist + return new DataResponse($this->l->t('File does not exist'), 400); + } + } /** * @param $string * @param $test * @return bool */ - private function endsWith($string, $test): bool { - $strlen = strlen($string); - $testlen = strlen($test); - if ($testlen > $strlen) return false; - return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0; - } + private function endsWith($string, $test): bool { + $strlen = strlen($string); + $testlen = strlen($test); + if ($testlen > $strlen) { + return false; + } + return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0; + } /** * @NoAdminRequired @@ -353,7 +339,7 @@ private function endsWith($string, $test): bool { * @throws \OCP\Files\NotPermittedException * @throws \OC\User\NoUserException */ - public function getSharedDevices(?int $myMapId=null): DataResponse { + public function getSharedDevices(?int $myMapId = null): DataResponse { if (is_null($myMapId) || $myMapId === '') { $sharedDevices = []; } else { @@ -378,10 +364,9 @@ public function shareDevice(int $id, int $timestampFrom, int $timestampTo): Data $share = $this->deviceShareMapper->create($id, $timestampFrom, $timestampTo); if ($share === null) { - return new DataResponse($this->l->t("Error sharing device"), Http::STATUS_INTERNAL_SERVER_ERROR); + return new DataResponse($this->l->t('Error sharing device'), Http::STATUS_INTERNAL_SERVER_ERROR); } - } - else { + } else { return new DataResponse($this->l->t('No such device'), 400); } @@ -398,7 +383,7 @@ public function shareDevice(int $id, int $timestampFrom, int $timestampTo): Data public function removeDeviceShare(int $token): DataResponse { try { $share = $this->deviceShareMapper->findByToken($token); - } catch ( DoesNotExistException $e ) { + } catch (DoesNotExistException $e) { throw new NotFoundException(); } $device = $this->devicesService->getDeviceFromDB($share->getDeviceId(), $this->userId); @@ -419,18 +404,18 @@ public function removeDeviceShare(int $token): DataResponse { public function addSharedDeviceToMap(string $token, $targetMapId): DataResponse { try { $share = $this->deviceShareMapper->findByToken($token); - } catch ( DoesNotExistException $e ) { + } catch (DoesNotExistException $e) { return new DataResponse($this->l->t('Share not Found'), 404); } $folders = $this->userfolder->getById($targetMapId); $folder = array_shift($folders); - if(is_null($folder)) { + if (is_null($folder)) { return new DataResponse($this->l->t('Map not Found'), 404); } try { - $file=$folder->get(".device_shares.json"); + $file = $folder->get('.device_shares.json'); } catch (\OCP\Files\NotFoundException $e) { - $file=$folder->newFile(".device_shares.json", $content = '[]'); + $file = $folder->newFile('.device_shares.json', $content = '[]'); } $data = json_decode($file->getContent(), true); foreach ($data as $s) { @@ -439,27 +424,27 @@ public function addSharedDeviceToMap(string $token, $targetMapId): DataResponse } } $data[] = $share; - $file->putContent(json_encode($data,JSON_PRETTY_PRINT)); + $file->putContent(json_encode($data, JSON_PRETTY_PRINT)); return new DataResponse('Done'); } public function removeSharedDeviceFromMap(string $token, int $myMapId): DataResponse { $folders = $this->userfolder->getById($myMapId); $folder = array_shift($folders); - if(is_null($folder)) { + if (is_null($folder)) { return new DataResponse($this->l->t('Map not Found'), 404); } try { - $file=$folder->get(".device_shares.json"); + $file = $folder->get('.device_shares.json'); } catch (\OCP\Files\NotFoundException $e) { - $file=$folder->newFile(".device_shares.json", $content = '[]'); + $file = $folder->newFile('.device_shares.json', $content = '[]'); } $data = json_decode($file->getContent(), true); $shares = []; $deleted = null; foreach ($data as $share) { - $t = $share["token"]; - if($t === $token) { + $t = $share['token']; + if ($t === $token) { $deleted = $share; } else { $shares[] = $share; diff --git a/lib/Controller/FavoritesApiController.php b/lib/Controller/FavoritesApiController.php index f833554b5..bd312d79d 100644 --- a/lib/Controller/FavoritesApiController.php +++ b/lib/Controller/FavoritesApiController.php @@ -16,64 +16,64 @@ use OCP\AppFramework\ApiController; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; +use OCP\IConfig; +use OCP\IGroupManager; use OCP\IL10N; +use OCP\ILogger; use OCP\IRequest; +use OCP\IServerContainer; use OCP\IUserManager; use OCP\Share\IManager; -use OCP\IServerContainer; -use OCP\IGroupManager; -use OCP\ILogger; -use OCP\IConfig; class FavoritesApiController extends ApiController { - private $userId; - private $userfolder; - private $config; - private $appVersion; - private $shareManager; - private $userManager; - private $groupManager; - private $dbtype; - private $dbdblquotes; - private $defaultDeviceId; - private $l; - private $logger; - private $favoritesService; - protected $appName; + private $userId; + private $userfolder; + private $config; + private $appVersion; + private $shareManager; + private $userManager; + private $groupManager; + private $dbtype; + private $dbdblquotes; + private $defaultDeviceId; + private $l; + private $logger; + private $favoritesService; + protected $appName; - public function __construct($AppName, - IRequest $request, - IServerContainer $serverContainer, - IConfig $config, - IManager $shareManager, - IAppManager $appManager, - IUserManager $userManager, - IGroupManager $groupManager, - IL10N $l, - ILogger $logger, - FavoritesService $favoritesService, - $UserId) { - parent::__construct($AppName, $request, - 'PUT, POST, GET, DELETE, PATCH, OPTIONS', - 'Authorization, Content-Type, Accept', - 1728000); - $this->favoritesService = $favoritesService; - $this->logger = $logger; - $this->appName = $AppName; - $this->appVersion = $config->getAppValue('maps', 'installed_version'); - $this->userId = $UserId; - $this->userManager = $userManager; - $this->groupManager = $groupManager; - $this->l = $l; - $this->dbtype = $config->getSystemValue('dbtype'); - // IConfig object - $this->config = $config; - if ($UserId !== '' and $UserId !== null and $serverContainer !== null) { - // path of user files folder relative to DATA folder - $this->userfolder = $serverContainer->getUserFolder($UserId); - } - $this->shareManager = $shareManager; - } + public function __construct($AppName, + IRequest $request, + IServerContainer $serverContainer, + IConfig $config, + IManager $shareManager, + IAppManager $appManager, + IUserManager $userManager, + IGroupManager $groupManager, + IL10N $l, + ILogger $logger, + FavoritesService $favoritesService, + $UserId) { + parent::__construct($AppName, $request, + 'PUT, POST, GET, DELETE, PATCH, OPTIONS', + 'Authorization, Content-Type, Accept', + 1728000); + $this->favoritesService = $favoritesService; + $this->logger = $logger; + $this->appName = $AppName; + $this->appVersion = $config->getAppValue('maps', 'installed_version'); + $this->userId = $UserId; + $this->userManager = $userManager; + $this->groupManager = $groupManager; + $this->l = $l; + $this->dbtype = $config->getSystemValue('dbtype'); + // IConfig object + $this->config = $config; + if ($UserId !== '' and $UserId !== null and $serverContainer !== null) { + // path of user files folder relative to DATA folder + $this->userfolder = $serverContainer->getUserFolder($UserId); + } + $this->shareManager = $shareManager; + } /** * @NoAdminRequired @@ -83,19 +83,19 @@ public function __construct($AppName, * @param int $pruneBefore * @return DataResponse */ - public function getFavorites($apiversion, int $pruneBefore = 0): DataResponse { - $now = new \DateTime(); + public function getFavorites($apiversion, int $pruneBefore = 0): DataResponse { + $now = new \DateTime(); - $favorites = $this->favoritesService->getFavoritesFromDB($this->userId, $pruneBefore); + $favorites = $this->favoritesService->getFavoritesFromDB($this->userId, $pruneBefore); - $etag = md5(json_encode($favorites)); - if ($this->request->getHeader('If-None-Match') === '"' . $etag . '"') { - return new DataResponse([], Http::STATUS_NOT_MODIFIED); - } - return (new DataResponse($favorites)) - ->setLastModified($now) - ->setETag($etag); - } + $etag = md5(json_encode($favorites)); + if ($this->request->getHeader('If-None-Match') === '"' . $etag . '"') { + return new DataResponse([], Http::STATUS_NOT_MODIFIED); + } + return (new DataResponse($favorites)) + ->setLastModified($now) + ->setETag($etag); + } /** * @NoAdminRequired @@ -110,15 +110,15 @@ public function getFavorites($apiversion, int $pruneBefore = 0): DataResponse { * @param $extensions * @return DataResponse */ - public function addFavorite($apiversion, $name, $lat, $lng, $category, $comment, $extensions): DataResponse { - if (is_numeric($lat) && is_numeric($lng)) { - $favoriteId = $this->favoritesService->addFavoriteToDB($this->userId, $name, $lat, $lng, $category, $comment, $extensions); - $favorite = $this->favoritesService->getFavoriteFromDB($favoriteId); - return new DataResponse($favorite); - } else { - return new DataResponse($this->l->t('Invalid values'), 400); - } - } + public function addFavorite($apiversion, $name, $lat, $lng, $category, $comment, $extensions): DataResponse { + if (is_numeric($lat) && is_numeric($lng)) { + $favoriteId = $this->favoritesService->addFavoriteToDB($this->userId, $name, $lat, $lng, $category, $comment, $extensions); + $favorite = $this->favoritesService->getFavoriteFromDB($favoriteId); + return new DataResponse($favorite); + } else { + return new DataResponse($this->l->t('Invalid values'), 400); + } + } /** * @NoAdminRequired @@ -133,22 +133,22 @@ public function addFavorite($apiversion, $name, $lat, $lng, $category, $comment, * @param $extensions * @return DataResponse */ - public function editFavorite($id, $name, $lat, $lng, $category, $comment, $extensions): DataResponse { - $favorite = $this->favoritesService->getFavoriteFromDB($id, $this->userId); - if ($favorite !== null) { - if (($lat === null || is_numeric($lat)) && - ($lng === null || is_numeric($lng)) - ) { - $this->favoritesService->editFavoriteInDB($id, $name, $lat, $lng, $category, $comment, $extensions); - $editedFavorite = $this->favoritesService->getFavoriteFromDB($id); - return new DataResponse($editedFavorite); - } else { - return new DataResponse($this->l->t('Invalid values'), 400); - } - } else { - return new DataResponse($this->l->t('No such favorite'), 400); - } - } + public function editFavorite($id, $name, $lat, $lng, $category, $comment, $extensions): DataResponse { + $favorite = $this->favoritesService->getFavoriteFromDB($id, $this->userId); + if ($favorite !== null) { + if (($lat === null || is_numeric($lat)) && + ($lng === null || is_numeric($lng)) + ) { + $this->favoritesService->editFavoriteInDB($id, $name, $lat, $lng, $category, $comment, $extensions); + $editedFavorite = $this->favoritesService->getFavoriteFromDB($id); + return new DataResponse($editedFavorite); + } else { + return new DataResponse($this->l->t('Invalid values'), 400); + } + } else { + return new DataResponse($this->l->t('No such favorite'), 400); + } + } /** * @NoAdminRequired @@ -157,14 +157,14 @@ public function editFavorite($id, $name, $lat, $lng, $category, $comment, $exten * @param $id * @return DataResponse */ - public function deleteFavorite($id): DataResponse { - $favorite = $this->favoritesService->getFavoriteFromDB($id, $this->userId); - if ($favorite !== null) { - $this->favoritesService->deleteFavoriteFromDB($id); - return new DataResponse('DELETED'); - } else { - return new DataResponse($this->l->t('No such favorite'), 400); - } - } + public function deleteFavorite($id): DataResponse { + $favorite = $this->favoritesService->getFavoriteFromDB($id, $this->userId); + if ($favorite !== null) { + $this->favoritesService->deleteFavoriteFromDB($id); + return new DataResponse('DELETED'); + } else { + return new DataResponse($this->l->t('No such favorite'), 400); + } + } } diff --git a/lib/Controller/FavoritesController.php b/lib/Controller/FavoritesController.php index 3a9b57500..3b46a9757 100644 --- a/lib/Controller/FavoritesController.php +++ b/lib/Controller/FavoritesController.php @@ -13,97 +13,97 @@ namespace OCA\Maps\Controller; -use OCP\Files\NotFoundException; use OCA\Maps\DB\FavoriteShareMapper; use OCA\Maps\Service\FavoritesService; use OCP\App\IAppManager; -use OCP\Share\IManager; -use OCP\IConfig; -use OCP\IUserManager; -use OCP\IGroupManager; -use OCP\ILogger; -use OCP\IServerContainer; use OCP\AppFramework\Controller; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\MultipleObjectsReturnedException; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; +use OCP\Files\NotFoundException; +use OCP\IConfig; use OCP\IDateTimeZone; +use OCP\IGroupManager; use OCP\IL10N; +use OCP\ILogger; use OCP\IRequest; +use OCP\IServerContainer; +use OCP\IUserManager; +use OCP\Share\IManager; class FavoritesController extends Controller { - private string $userId; - private \OCP\Files\Folder $userFolder; - private IConfig $config; - private string $appVersion; - private IManager $shareManager; - private IUserManager $userManager; - private IGroupManager $groupManager; - private string $dbtype; + private string $userId; + private \OCP\Files\Folder $userFolder; + private IConfig $config; + private string $appVersion; + private IManager $shareManager; + private IUserManager $userManager; + private IGroupManager $groupManager; + private string $dbtype; private IL10N $l; - private ILogger $logger; - private FavoritesService $favoritesService; - private IDateTimeZone $dateTimeZone; - private ?string $defaultFavoritsJSON; - protected $appName; - - /* @var FavoriteShareMapper */ - private $favoriteShareMapper; - - public function __construct($AppName, - IRequest $request, - IServerContainer $serverContainer, - IConfig $config, - IManager $shareManager, - IAppManager $appManager, - IUserManager $userManager, - IGroupManager $groupManager, - IL10N $l, - ILogger $logger, - FavoritesService $favoritesService, - IDateTimeZone $dateTimeZone, - FavoriteShareMapper $favoriteShareMapper, - $UserId) { - parent::__construct($AppName, $request); - $this->favoritesService = $favoritesService; - $this->dateTimeZone = $dateTimeZone; - $this->logger = $logger; - $this->appName = $AppName; - $this->appVersion = $config->getAppValue('maps', 'installed_version'); - $this->userId = $UserId; - $this->userManager = $userManager; - $this->groupManager = $groupManager; - $this->l = $l; - $this->dbtype = $config->getSystemValue('dbtype'); - // IConfig object - $this->config = $config; - if ($UserId !== '' and $UserId !== null and $serverContainer !== null) { - // path of user files folder relative to DATA folder - $this->userFolder = $serverContainer->getUserFolder($UserId); - } - $this->shareManager = $shareManager; - $this->favoriteShareMapper = $favoriteShareMapper; - $this->defaultFavoritsJSON = json_encode([ - "type" => "FeatureCollection", - "features"=> [] - ],JSON_PRETTY_PRINT); - } + private ILogger $logger; + private FavoritesService $favoritesService; + private IDateTimeZone $dateTimeZone; + private ?string $defaultFavoritsJSON; + protected $appName; + + /* @var FavoriteShareMapper */ + private $favoriteShareMapper; + + public function __construct($AppName, + IRequest $request, + IServerContainer $serverContainer, + IConfig $config, + IManager $shareManager, + IAppManager $appManager, + IUserManager $userManager, + IGroupManager $groupManager, + IL10N $l, + ILogger $logger, + FavoritesService $favoritesService, + IDateTimeZone $dateTimeZone, + FavoriteShareMapper $favoriteShareMapper, + $UserId) { + parent::__construct($AppName, $request); + $this->favoritesService = $favoritesService; + $this->dateTimeZone = $dateTimeZone; + $this->logger = $logger; + $this->appName = $AppName; + $this->appVersion = $config->getAppValue('maps', 'installed_version'); + $this->userId = $UserId; + $this->userManager = $userManager; + $this->groupManager = $groupManager; + $this->l = $l; + $this->dbtype = $config->getSystemValue('dbtype'); + // IConfig object + $this->config = $config; + if ($UserId !== '' and $UserId !== null and $serverContainer !== null) { + // path of user files folder relative to DATA folder + $this->userFolder = $serverContainer->getUserFolder($UserId); + } + $this->shareManager = $shareManager; + $this->favoriteShareMapper = $favoriteShareMapper; + $this->defaultFavoritsJSON = json_encode([ + 'type' => 'FeatureCollection', + 'features' => [] + ], JSON_PRETTY_PRINT); + } /** * @param \OCP\Files\Folder $folder * @return mixed * @throws \OCP\Files\NotPermittedException */ - private function getJSONFavoritesFile(\OCP\Files\Folder $folder): \OCP\Files\Node { - try { - $file = $folder->get('.favorites.json'); - } catch (NotFoundException $e) { - $file = $folder->newFile('.favorites.json', $content = $this->defaultFavoritsJSON); - } - return $file; - } + private function getJSONFavoritesFile(\OCP\Files\Folder $folder): \OCP\Files\Node { + try { + $file = $folder->get('.favorites.json'); + } catch (NotFoundException $e) { + $file = $folder->newFile('.favorites.json', $content = $this->defaultFavoritsJSON); + } + return $file; + } /** * @NoAdminRequired @@ -111,17 +111,17 @@ private function getJSONFavoritesFile(\OCP\Files\Folder $folder): \OCP\Files\Nod * @return DataResponse * @throws \OCP\Files\NotPermittedException */ - public function getFavorites(int $myMapId=null): DataResponse { - if (is_null($myMapId) || $myMapId === '') { - $favorites = $this->favoritesService->getFavoritesFromDB($this->userId); - } else { - $folders = $this->userFolder->getById($myMapId); - $folder = array_shift($folders); - $file = $this->getJSONFavoritesFile($folder); - $favorites = $this->favoritesService->getFavoritesFromJSON($file); - } - return new DataResponse($favorites); - } + public function getFavorites(?int $myMapId = null): DataResponse { + if (is_null($myMapId) || $myMapId === '') { + $favorites = $this->favoritesService->getFavoritesFromDB($this->userId); + } else { + $folders = $this->userFolder->getById($myMapId); + $folder = array_shift($folders); + $file = $this->getJSONFavoritesFile($folder); + $favorites = $this->favoritesService->getFavoritesFromJSON($file); + } + return new DataResponse($favorites); + } /** * @NoAdminRequired @@ -137,31 +137,31 @@ public function getFavorites(int $myMapId=null): DataResponse { * @throws \OCP\Files\InvalidPathException * @throws \OCP\Files\NotPermittedException */ - public function addFavorite(?string $name, float $lat, float $lng, ?string $category, ?string $comment, ?string $extensions, ?int $myMapId=null): DataResponse { - if (is_numeric($lat) && is_numeric($lng)) { - if (is_null($myMapId) || $myMapId === '') { - $favoriteId = $this->favoritesService->addFavoriteToDB($this->userId, $name, $lat, $lng, $category, $comment, $extensions); - $favorite = $this->favoritesService->getFavoriteFromDB($favoriteId); - return new DataResponse($favorite); - } else { - $folders = $this->userFolder->getById($myMapId); - if(!empty($folders) && $this->userFolder->getId() === $myMapId) { + public function addFavorite(?string $name, float $lat, float $lng, ?string $category, ?string $comment, ?string $extensions, ?int $myMapId = null): DataResponse { + if (is_numeric($lat) && is_numeric($lng)) { + if (is_null($myMapId) || $myMapId === '') { + $favoriteId = $this->favoritesService->addFavoriteToDB($this->userId, $name, $lat, $lng, $category, $comment, $extensions); + $favorite = $this->favoritesService->getFavoriteFromDB($favoriteId); + return new DataResponse($favorite); + } else { + $folders = $this->userFolder->getById($myMapId); + if (!empty($folders) && $this->userFolder->getId() === $myMapId) { $folders[] = $this->userFolder; } - $folder = array_shift($folders); - if(is_null($folder)) { + $folder = array_shift($folders); + if (is_null($folder)) { return new DataResponse('Map not found', 404); } - $file = $this->getJSONFavoritesFile($folder); - $favoriteId = $this->favoritesService->addFavoriteToJSON($file, $name, $lat, $lng, $category, $comment, $extensions); - $favorite = $this->favoritesService->getFavoriteFromJSON($file, $favoriteId); - return new DataResponse($favorite); - } + $file = $this->getJSONFavoritesFile($folder); + $favoriteId = $this->favoritesService->addFavoriteToJSON($file, $name, $lat, $lng, $category, $comment, $extensions); + $favorite = $this->favoritesService->getFavoriteFromJSON($file, $favoriteId); + return new DataResponse($favorite); + } - } else { - return new DataResponse($this->l->t('Invalid values'), 400); - } - } + } else { + return new DataResponse($this->l->t('Invalid values'), 400); + } + } /** * @NoAdminRequired @@ -172,32 +172,32 @@ public function addFavorite(?string $name, float $lat, float $lng, ?string $cate * @throws \OCP\Files\InvalidPathException * @throws \OCP\Files\NotPermittedException */ - public function addFavorites(array $favorites, ?int $myMapId=null): DataResponse { + public function addFavorites(array $favorites, ?int $myMapId = null): DataResponse { if (is_null($myMapId) || $myMapId === '') { $favoritesAfter = []; - forEach ($favorites as $favorite) { + foreach ($favorites as $favorite) { if (is_numeric($favorite->lat) && is_numeric($favorite->lng)) { $favoriteId = $this->favoritesService->addFavoriteToDB($this->userId, $favorite->name, $favorite->lat, $favorite->lng, $favorite->category, $favorite->comment, $favorite->extensions); $favoritesAfter[] = $this->favoritesService->getFavoriteFromDB($favoriteId); - } else { + } else { return new DataResponse('invalid values', 400); } } return new DataResponse($favoritesAfter); } else { $folders = $this->userFolder->getById($myMapId); - if(!empty($folders) && $this->userFolder->getId() === $myMapId) { + if (!empty($folders) && $this->userFolder->getId() === $myMapId) { $folders[] = $this->userFolder; } $folder = array_shift($folders); - if(is_null($folder)) { + if (is_null($folder)) { return new DataResponse('Map not found', 404); } $file = $this->getJSONFavoritesFile($folder); $favoriteIds = $this->favoritesService->addFavoritesToJSON($file, $favorites); $favoritesAfter = []; - forEach ($this->favoritesService->getFavoritesFromJSON($file) as $favorite) { - if (in_array($favorite['id'],$favoriteIds)) { + foreach ($this->favoritesService->getFavoritesFromJSON($file) as $favorite) { + if (in_array($favorite['id'], $favoriteIds)) { $favoritesAfter[] = $favorite; } }; @@ -218,26 +218,26 @@ public function addFavorites(array $favorites, ?int $myMapId=null): DataResponse * @return DataResponse * @throws \OCP\Files\NotPermittedException */ - public function editFavorite(int $id, ?string $name, float $lat, float $lng, ?string $category, ?string $comment, ?string $extensions, ?int $myMapId=null): DataResponse { - if (is_null($myMapId) || $myMapId==='') { - $favorite = $this->favoritesService->getFavoriteFromDB($id, $this->userId); - if ($favorite !== null) { - if (($lat === null || is_numeric($lat)) && - ($lng === null || is_numeric($lng)) - ) { - $this->favoritesService->editFavoriteInDB($id, $name, $lat, $lng, $category, $comment, $extensions); - $editedFavorite = $this->favoritesService->getFavoriteFromDB($id); - return new DataResponse($editedFavorite); - } else { - return new DataResponse($this->l->t('invalid values'), 400); - } - } else { - return new DataResponse($this->l->t('no such favorite'), 400); - } - } else { - $folders = $this->userFolder->getById($myMapId); - $folder = array_shift($folders); - $file = $this->getJSONFavoritesFile($folder); + public function editFavorite(int $id, ?string $name, float $lat, float $lng, ?string $category, ?string $comment, ?string $extensions, ?int $myMapId = null): DataResponse { + if (is_null($myMapId) || $myMapId === '') { + $favorite = $this->favoritesService->getFavoriteFromDB($id, $this->userId); + if ($favorite !== null) { + if (($lat === null || is_numeric($lat)) && + ($lng === null || is_numeric($lng)) + ) { + $this->favoritesService->editFavoriteInDB($id, $name, $lat, $lng, $category, $comment, $extensions); + $editedFavorite = $this->favoritesService->getFavoriteFromDB($id); + return new DataResponse($editedFavorite); + } else { + return new DataResponse($this->l->t('invalid values'), 400); + } + } else { + return new DataResponse($this->l->t('no such favorite'), 400); + } + } else { + $folders = $this->userFolder->getById($myMapId); + $folder = array_shift($folders); + $file = $this->getJSONFavoritesFile($folder); $favorite = $this->favoritesService->getFavoriteFromJSON($file, $id, $this->userId); if ($favorite !== null) { if (($lat === null || is_numeric($lat)) && @@ -252,8 +252,8 @@ public function editFavorite(int $id, ?string $name, float $lat, float $lng, ?st } else { return new DataResponse($this->l->t('no such favorite'), 400); } - } - } + } + } /** * @NoAdminRequired @@ -264,29 +264,29 @@ public function editFavorite(int $id, ?string $name, float $lat, float $lng, ?st * @throws \OCP\DB\Exception * @throws \OCP\Files\NotPermittedException */ - public function renameCategories(array $categories, string $newName, ?int $myMapId=null): DataResponse { - if (is_array($categories)) { - foreach ($categories as $cat) { - if (is_null($myMapId) || $myMapId === ""){ - $this->favoritesService->renameCategoryInDB($this->userId, $cat, $newName); - - // Rename share if one exists - try { - $share = $this->favoriteShareMapper->findByOwnerAndCategory($this->userId, $cat); - $share->setCategory($newName); - $this->favoriteShareMapper->update($share); - } catch (DoesNotExistException | MultipleObjectsReturnedException $e) { - } - } else { - $folders = $this->userFolder->getById($myMapId); - $folder = array_shift($folders); - $file = $this->getJSONFavoritesFile($folder); - $this->favoritesService->renameCategoryInJSON($file, $cat, $newName); - } - } - } - return new DataResponse('RENAMED'); - } + public function renameCategories(array $categories, string $newName, ?int $myMapId = null): DataResponse { + if (is_array($categories)) { + foreach ($categories as $cat) { + if (is_null($myMapId) || $myMapId === '') { + $this->favoritesService->renameCategoryInDB($this->userId, $cat, $newName); + + // Rename share if one exists + try { + $share = $this->favoriteShareMapper->findByOwnerAndCategory($this->userId, $cat); + $share->setCategory($newName); + $this->favoriteShareMapper->update($share); + } catch (DoesNotExistException|MultipleObjectsReturnedException $e) { + } + } else { + $folders = $this->userFolder->getById($myMapId); + $folder = array_shift($folders); + $file = $this->getJSONFavoritesFile($folder); + $this->favoritesService->renameCategoryInJSON($file, $cat, $newName); + } + } + } + return new DataResponse('RENAMED'); + } /** * @NoAdminRequired @@ -295,15 +295,15 @@ public function renameCategories(array $categories, string $newName, ?int $myMap * @return DataResponse * @throws \OCP\Files\NotPermittedException */ - public function deleteFavorite(int $id, ?int $myMapId=null): DataResponse { - if (is_null($myMapId) || $myMapId === "") { - $favorite = $this->favoritesService->getFavoriteFromDB($id, $this->userId); - if ($favorite !== null) { - $this->favoritesService->deleteFavoriteFromDB($id); - return new DataResponse('DELETED'); - } + public function deleteFavorite(int $id, ?int $myMapId = null): DataResponse { + if (is_null($myMapId) || $myMapId === '') { + $favorite = $this->favoritesService->getFavoriteFromDB($id, $this->userId); + if ($favorite !== null) { + $this->favoritesService->deleteFavoriteFromDB($id); + return new DataResponse('DELETED'); + } return new DataResponse($this->l->t('no such favorite'), 400); - } + } $folders = $this->userFolder->getById($myMapId); $folder = array_shift($folders); $file = $this->getJSONFavoritesFile($folder); @@ -311,7 +311,7 @@ public function deleteFavorite(int $id, ?int $myMapId=null): DataResponse { return new DataResponse('DELETED'); } return new DataResponse($this->l->t('no such favorite'), 400); - } + } /** * @NoAdminRequired @@ -320,17 +320,17 @@ public function deleteFavorite(int $id, ?int $myMapId=null): DataResponse { * @return DataResponse * @throws \OCP\Files\NotPermittedException */ - public function deleteFavorites(array $ids, ?int $myMapId=null): DataResponse { - if (is_null($myMapId) || $myMapId === "") { - $this->favoritesService->deleteFavoritesFromDB($ids, $this->userId); - } else { - $folders = $this->userFolder->getById($myMapId); - $folder = array_shift($folders); - $file = $this->getJSONFavoritesFile($folder); - $this->favoritesService->deleteFavoritesFromJSON($file, $ids); - } - return new DataResponse('DELETED'); - } + public function deleteFavorites(array $ids, ?int $myMapId = null): DataResponse { + if (is_null($myMapId) || $myMapId === '') { + $this->favoritesService->deleteFavoritesFromDB($ids, $this->userId); + } else { + $folders = $this->userFolder->getById($myMapId); + $folder = array_shift($folders); + $file = $this->getJSONFavoritesFile($folder); + $this->favoritesService->deleteFavoritesFromJSON($file, $ids); + } + return new DataResponse('DELETED'); + } /** * @NoAdminRequired @@ -339,51 +339,51 @@ public function deleteFavorites(array $ids, ?int $myMapId=null): DataResponse { * @throws \OCP\Files\NotPermittedException * @throws \OC\User\NoUserException */ - public function getSharedCategories(?int $myMapId=null): DataResponse { + public function getSharedCategories(?int $myMapId = null): DataResponse { if (is_null($myMapId) || $myMapId === '') { $categories = $this->favoriteShareMapper->findAllByOwner($this->userId); } else { $categories = $this->favoriteShareMapper->findAllByMapId($this->userId, $myMapId); } - return new DataResponse($categories); - } + return new DataResponse($categories); + } /** * @NoAdminRequired * @param string $category * @return DataResponse */ - public function shareCategory(string $category): DataResponse { - if ($this->favoritesService->countFavorites($this->userId, [$category], null, null) === 0) { - return new DataResponse($this->l->t("Unknown category"), Http::STATUS_BAD_REQUEST); - } + public function shareCategory(string $category): DataResponse { + if ($this->favoritesService->countFavorites($this->userId, [$category], null, null) === 0) { + return new DataResponse($this->l->t('Unknown category'), Http::STATUS_BAD_REQUEST); + } - $share = $this->favoriteShareMapper->findOrCreateByOwnerAndCategory($this->userId, $category); + $share = $this->favoriteShareMapper->findOrCreateByOwnerAndCategory($this->userId, $category); - if ($share === null) { - return new DataResponse($this->l->t("Error sharing favorite"), Http::STATUS_INTERNAL_SERVER_ERROR); - } + if ($share === null) { + return new DataResponse($this->l->t('Error sharing favorite'), Http::STATUS_INTERNAL_SERVER_ERROR); + } - return new DataResponse($share); - } + return new DataResponse($share); + } /** * @NoAdminRequired * @param string $category * @return DataResponse */ - public function unShareCategory(string $category): DataResponse { - if ($this->favoritesService->countFavorites($this->userId, [$category], null, null) === 0) { - return new DataResponse($this->l->t("Unknown category"), Http::STATUS_BAD_REQUEST); - } + public function unShareCategory(string $category): DataResponse { + if ($this->favoritesService->countFavorites($this->userId, [$category], null, null) === 0) { + return new DataResponse($this->l->t('Unknown category'), Http::STATUS_BAD_REQUEST); + } - $didExist = $this->favoriteShareMapper->removeByOwnerAndCategory($this->userId, $category); + $didExist = $this->favoriteShareMapper->removeByOwnerAndCategory($this->userId, $category); - return new DataResponse([ - 'did_exist' => $didExist - ]); - } + return new DataResponse([ + 'did_exist' => $didExist + ]); + } /** * @NoAdminRequired @@ -396,21 +396,21 @@ public function unShareCategory(string $category): DataResponse { * @throws \OCP\Files\NotPermittedException * @throws \OC\User\NoUserException */ - public function addShareCategoryToMap(string $category, int $targetMapId, ?int $myMapId=null): DataResponse { - if (is_null($myMapId) || $myMapId==='') { + public function addShareCategoryToMap(string $category, int $targetMapId, ?int $myMapId = null): DataResponse { + if (is_null($myMapId) || $myMapId === '') { $share = $this->favoriteShareMapper->findByOwnerAndCategory($this->userId, $category); } else { $share = $this->favoriteShareMapper->findByMapIdAndCategory($this->userId, $myMapId, $category); } $folders = $this->userFolder->getById($targetMapId); $folder = array_shift($folders); - if(is_null($folder)) { + if (is_null($folder)) { return new DataResponse($this->l->t('Map not Found'), 404); } try { - $file=$folder->get(".favorite_shares.json"); + $file = $folder->get('.favorite_shares.json'); } catch (NotFoundException $e) { - $file=$folder->newFile(".favorite_shares.json", $content = '[]'); + $file = $folder->newFile('.favorite_shares.json', $content = '[]'); } $data = json_decode($file->getContent(), true); foreach ($data as $s) { @@ -420,7 +420,7 @@ public function addShareCategoryToMap(string $category, int $targetMapId, ?int $ } $share->id = count($data); $data[] = $share; - $file->putContent(json_encode($data,JSON_PRETTY_PRINT)); + $file->putContent(json_encode($data, JSON_PRETTY_PRINT)); return new DataResponse('Done'); } @@ -448,60 +448,58 @@ public function removeShareCategoryFromMap(string $category, int $myMapId): Data * @throws NotFoundException * @throws \OCP\Files\NotPermittedException */ - public function exportFavorites(?array $categoryList = null, ?int $begin = null, ?int $end = null, bool $all = false): DataResponse { - // sorry about ugly categoryList management: - // when an empty list is passed in http request, we get null here - if ($categoryList === null or (is_array($categoryList) and count($categoryList) === 0)) { - $response = new DataResponse($this->l->t('Nothing to export'), 400); - return $response; - } - - // create /Maps directory if necessary - $userFolder = $this->userFolder; - if (!$userFolder->nodeExists('/Maps')) { - $userFolder->newFolder('Maps'); - } - if ($userFolder->nodeExists('/Maps')) { - $mapsFolder = $userFolder->get('/Maps'); - if ($mapsFolder->getType() !== \OCP\Files\FileInfo::TYPE_FOLDER) { - $response = new DataResponse($this->l->t('/Maps is not a directory'), 400); - return $response; - } - else if (!$mapsFolder->isCreatable()) { - $response = new DataResponse($this->l->t('/Maps directory is not writeable'), 400); - return $response; - } - } - else { - $response = new DataResponse($this->l->t('Impossible to create /Maps directory'), 400); - return $response; - } - - $nbFavorites = $this->favoritesService->countFavorites($this->userId, $categoryList, $begin, $end); - if ($nbFavorites === 0) { - $response = new DataResponse($this->l->t('Nothing to export'), 400); - return $response; - } - - // generate export file name - $prefix = $all ? '' : 'filtered-'; - $tz = $this->dateTimeZone->getTimeZone(); - $now = new \DateTime('now', $tz); - $dateStr = $now->format('Y-m-d H:i:s (P)'); - $filename = $dateStr.' '.$prefix.'favorites.gpx'; - - if ($mapsFolder->nodeExists($filename)) { - $mapsFolder->get($filename)->delete(); - } - $file = $mapsFolder->newFile($filename); - $handler = $file->fopen('w'); - - $this->favoritesService->exportFavorites($this->userId, $handler, $categoryList, $begin, $end, $this->appVersion); - - fclose($handler); - $file->touch(); - return new DataResponse('/Maps/'.$filename); - } + public function exportFavorites(?array $categoryList = null, ?int $begin = null, ?int $end = null, bool $all = false): DataResponse { + // sorry about ugly categoryList management: + // when an empty list is passed in http request, we get null here + if ($categoryList === null or (is_array($categoryList) and count($categoryList) === 0)) { + $response = new DataResponse($this->l->t('Nothing to export'), 400); + return $response; + } + + // create /Maps directory if necessary + $userFolder = $this->userFolder; + if (!$userFolder->nodeExists('/Maps')) { + $userFolder->newFolder('Maps'); + } + if ($userFolder->nodeExists('/Maps')) { + $mapsFolder = $userFolder->get('/Maps'); + if ($mapsFolder->getType() !== \OCP\Files\FileInfo::TYPE_FOLDER) { + $response = new DataResponse($this->l->t('/Maps is not a directory'), 400); + return $response; + } elseif (!$mapsFolder->isCreatable()) { + $response = new DataResponse($this->l->t('/Maps directory is not writeable'), 400); + return $response; + } + } else { + $response = new DataResponse($this->l->t('Impossible to create /Maps directory'), 400); + return $response; + } + + $nbFavorites = $this->favoritesService->countFavorites($this->userId, $categoryList, $begin, $end); + if ($nbFavorites === 0) { + $response = new DataResponse($this->l->t('Nothing to export'), 400); + return $response; + } + + // generate export file name + $prefix = $all ? '' : 'filtered-'; + $tz = $this->dateTimeZone->getTimeZone(); + $now = new \DateTime('now', $tz); + $dateStr = $now->format('Y-m-d H:i:s (P)'); + $filename = $dateStr.' '.$prefix.'favorites.gpx'; + + if ($mapsFolder->nodeExists($filename)) { + $mapsFolder->get($filename)->delete(); + } + $file = $mapsFolder->newFile($filename); + $handler = $file->fopen('w'); + + $this->favoritesService->exportFavorites($this->userId, $handler, $categoryList, $begin, $end, $this->appVersion); + + fclose($handler); + $file->touch(); + return new DataResponse('/Maps/'.$filename); + } /** * @NoAdminRequired @@ -510,45 +508,44 @@ public function exportFavorites(?array $categoryList = null, ?int $begin = null, * @throws NotFoundException * @throws \OCP\Files\InvalidPathException */ - public function importFavorites(string $path): DataResponse { - $userFolder = $this->userFolder; - $cleanpath = str_replace(array('../', '..\\'), '',$path); - - if ($userFolder->nodeExists($cleanpath)){ - $file = $userFolder->get($cleanpath); - if ($file->getType() === \OCP\Files\FileInfo::TYPE_FILE and - $file->isReadable()){ - $lowerFileName = strtolower($file->getName()); - if ($this->endswith($lowerFileName, '.gpx') or $this->endswith($lowerFileName, '.kml') or $this->endswith($lowerFileName, '.kmz') or $this->endswith($lowerFileName, '.json') or $this->endswith($lowerFileName, '.geojson')) { - $result = $this->favoritesService->importFavorites($this->userId, $file); - return new DataResponse($result); - } - else { - // invalid extension - return new DataResponse($this->l->t('Invalid file extension'), 400); - } - } - else { - // directory or not readable - return new DataResponse($this->l->t('Impossible to read the file'), 400); - } - } - else { - // does not exist - return new DataResponse($this->l->t('File does not exist'), 400); - } - } + public function importFavorites(string $path): DataResponse { + $userFolder = $this->userFolder; + $cleanpath = str_replace(['../', '..\\'], '', $path); + + if ($userFolder->nodeExists($cleanpath)) { + $file = $userFolder->get($cleanpath); + if ($file->getType() === \OCP\Files\FileInfo::TYPE_FILE and + $file->isReadable()) { + $lowerFileName = strtolower($file->getName()); + if ($this->endswith($lowerFileName, '.gpx') or $this->endswith($lowerFileName, '.kml') or $this->endswith($lowerFileName, '.kmz') or $this->endswith($lowerFileName, '.json') or $this->endswith($lowerFileName, '.geojson')) { + $result = $this->favoritesService->importFavorites($this->userId, $file); + return new DataResponse($result); + } else { + // invalid extension + return new DataResponse($this->l->t('Invalid file extension'), 400); + } + } else { + // directory or not readable + return new DataResponse($this->l->t('Impossible to read the file'), 400); + } + } else { + // does not exist + return new DataResponse($this->l->t('File does not exist'), 400); + } + } /** * @param string $string * @param string $test * @return bool */ - private function endswith(string $string, string $test): bool { - $strlen = strlen($string); - $testlen = strlen($test); - if ($testlen > $strlen) return false; - return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0; - } + private function endswith(string $string, string $test): bool { + $strlen = strlen($string); + $testlen = strlen($test); + if ($testlen > $strlen) { + return false; + } + return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0; + } } diff --git a/lib/Controller/MyMapsController.php b/lib/Controller/MyMapsController.php index 7783e0a2b..9882291fd 100644 --- a/lib/Controller/MyMapsController.php +++ b/lib/Controller/MyMapsController.php @@ -14,61 +14,56 @@ namespace OCA\Maps\Controller; use OCA\Maps\Service\MyMapsService; -use OCP\Files\NotFoundException; -use OCA\Maps\DB\FavoriteShareMapper; use OCP\AppFramework\Controller; -use OCP\AppFramework\Db\DoesNotExistException; -use OCP\AppFramework\Db\MultipleObjectsReturnedException; -use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\IRequest; class MyMapsController extends Controller { - /* @var MyMapsService */ - private $myMapsService; + /* @var MyMapsService */ + private $myMapsService; private $userId; - public function __construct(string $AppName, IRequest $request, MyMapsService $myMapsService, $userId) { - parent::__construct($AppName, $request); - $this->myMapsService = $myMapsService; + public function __construct(string $AppName, IRequest $request, MyMapsService $myMapsService, $userId) { + parent::__construct($AppName, $request); + $this->myMapsService = $myMapsService; $this->userId = $userId; - } + } - /** - * @NoAdminRequired - */ - public function addMyMap(array $values): DataResponse { - $newName = $values["newName"] ?? "New Map"; - $myMap = $this->myMapsService->addMyMap($newName, $this->userId); - if (is_string($myMap)) { - new DataResponse($myMap, 400); - } - return new DataResponse($myMap); - } + /** + * @NoAdminRequired + */ + public function addMyMap(array $values): DataResponse { + $newName = $values['newName'] ?? 'New Map'; + $myMap = $this->myMapsService->addMyMap($newName, $this->userId); + if (is_string($myMap)) { + new DataResponse($myMap, 400); + } + return new DataResponse($myMap); + } - /** - * @NoAdminRequired - */ - public function updateMyMap(int $id, array $values): DataResponse { - $myMap = $this->myMapsService->updateMyMap($id, $values, $this->userId); - return new DataResponse($myMap); - } + /** + * @NoAdminRequired + */ + public function updateMyMap(int $id, array $values): DataResponse { + $myMap = $this->myMapsService->updateMyMap($id, $values, $this->userId); + return new DataResponse($myMap); + } - /** - * @NoAdminRequired - */ - public function deleteMyMap(int $id): DataResponse { - $result = $this->myMapsService->deleteMyMap($id, $this->userId); - return new DataResponse($result); - } + /** + * @NoAdminRequired + */ + public function deleteMyMap(int $id): DataResponse { + $result = $this->myMapsService->deleteMyMap($id, $this->userId); + return new DataResponse($result); + } - /** - * @NoAdminRequired - */ - public function getMyMaps(): DataResponse { - $myMaps = $this->myMapsService->getAllMyMaps($this->userId); - return new DataResponse($myMaps); - } + /** + * @NoAdminRequired + */ + public function getMyMaps(): DataResponse { + $myMaps = $this->myMapsService->getAllMyMaps($this->userId); + return new DataResponse($myMaps); + } } diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 3e3aa390c..949094b9e 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -13,32 +13,32 @@ use OCA\Files\Event\LoadSidebar; use OCA\Viewer\Event\LoadViewer; -use OCP\IConfig; -use OCP\IRequest; +use OCP\AppFramework\Controller; use OCP\AppFramework\Http\TemplateResponse; use OCP\EventDispatcher\IEventDispatcher; -use OCP\AppFramework\Controller; +use OCP\IConfig; use OCP\IInitialStateService; +use OCP\IRequest; class PageController extends Controller { - private $userId; - private $config; - - /** @var IEventDispatcher */ - private $eventDispatcher; - - public function __construct($AppName, - IRequest $request, - IEventDispatcher $eventDispatcher, - IConfig $config, - IInitialStateService $initialStateService, - $UserId){ - parent::__construct($AppName, $request); - $this->userId = $UserId; - $this->eventDispatcher = $eventDispatcher; - $this->config = $config; - $this->initialStateService = $initialStateService; - } + private $userId; + private $config; + + /** @var IEventDispatcher */ + private $eventDispatcher; + + public function __construct($AppName, + IRequest $request, + IEventDispatcher $eventDispatcher, + IConfig $config, + IInitialStateService $initialStateService, + $UserId) { + parent::__construct($AppName, $request); + $this->userId = $UserId; + $this->eventDispatcher = $eventDispatcher; + $this->config = $config; + $this->initialStateService = $initialStateService; + } /** * CAUTION: the @Stuff turns off security checks; for this page no admin is @@ -51,35 +51,35 @@ public function __construct($AppName, * @NoCSRFRequired * @return TemplateResponse */ - public function index(): TemplateResponse { - $this->eventDispatcher->dispatch(LoadSidebar::class, new LoadSidebar()); - $this->eventDispatcher->dispatch(LoadViewer::class, new LoadViewer()); + public function index(): TemplateResponse { + $this->eventDispatcher->dispatch(LoadSidebar::class, new LoadSidebar()); + $this->eventDispatcher->dispatch(LoadViewer::class, new LoadViewer()); - $params = array('user' => $this->userId); - $this->initialStateService->provideInitialState($this->appName, 'photos', $this->config->getAppValue('photos', 'enabled', 'no') === 'yes'); - $response = new TemplateResponse('maps', 'main', $params); + $params = ['user' => $this->userId]; + $this->initialStateService->provideInitialState($this->appName, 'photos', $this->config->getAppValue('photos', 'enabled', 'no') === 'yes'); + $response = new TemplateResponse('maps', 'main', $params); - $this->addCsp($response); + $this->addCsp($response); - return $response; - } + return $response; + } - /** - * @NoAdminRequired - * @NoCSRFRequired - */ - public function indexMyMap($myMapId): TemplateResponse { - $this->eventDispatcher->dispatch(LoadSidebar::class, new LoadSidebar()); - $this->eventDispatcher->dispatch(LoadViewer::class, new LoadViewer()); + /** + * @NoAdminRequired + * @NoCSRFRequired + */ + public function indexMyMap($myMapId): TemplateResponse { + $this->eventDispatcher->dispatch(LoadSidebar::class, new LoadSidebar()); + $this->eventDispatcher->dispatch(LoadViewer::class, new LoadViewer()); - $params = array('user' => $this->userId); - $this->initialStateService->provideInitialState($this->appName, 'photos', $this->config->getAppValue('photos', 'enabled', 'no') === 'yes'); - $response = new TemplateResponse('maps', 'main', $params); + $params = ['user' => $this->userId]; + $this->initialStateService->provideInitialState($this->appName, 'photos', $this->config->getAppValue('photos', 'enabled', 'no') === 'yes'); + $response = new TemplateResponse('maps', 'main', $params); - $this->addCsp($response); + $this->addCsp($response); - return $response; - } + return $response; + } /** * @NoAdminRequired @@ -87,64 +87,64 @@ public function indexMyMap($myMapId): TemplateResponse { * @param $url * @return TemplateResponse */ - public function openGeoLink($url): TemplateResponse { - return $this->index(); - } + public function openGeoLink($url): TemplateResponse { + return $this->index(); + } /** * @param $response * @return void */ - private function addCsp($response): void { - if (class_exists('OCP\AppFramework\Http\ContentSecurityPolicy')) { - $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy(); - // map tiles - $csp->addAllowedImageDomain('https://*.tile.openstreetmap.org'); - $csp->addAllowedImageDomain('https://server.arcgisonline.com'); - $csp->addAllowedImageDomain('https://*.cartocdn.com'); - $csp->addAllowedImageDomain('https://*.opentopomap.org'); - $csp->addAllowedImageDomain('https://*.cartocdn.com'); - $csp->addAllowedImageDomain('https://*.ssl.fastly.net'); - $csp->addAllowedImageDomain('https://*.openstreetmap.se'); - - // default routing engine - $csp->addAllowedConnectDomain('https://*.project-osrm.org'); - $csp->addAllowedConnectDomain('https://api.mapbox.com'); - $csp->addAllowedConnectDomain('https://events.mapbox.com'); - $csp->addAllowedConnectDomain('https://graphhopper.com'); - - $csp->addAllowedChildSrcDomain('blob:'); - $csp->addAllowedWorkerSrcDomain('blob:'); - $csp->addAllowedScriptDomain('https://unpkg.com'); - // allow connections to custom routing engines - $urlKeys = [ - 'osrmBikeURL', - 'osrmCarURL', - 'osrmFootURL', - 'graphhopperURL', + private function addCsp($response): void { + if (class_exists('OCP\AppFramework\Http\ContentSecurityPolicy')) { + $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy(); + // map tiles + $csp->addAllowedImageDomain('https://*.tile.openstreetmap.org'); + $csp->addAllowedImageDomain('https://server.arcgisonline.com'); + $csp->addAllowedImageDomain('https://*.cartocdn.com'); + $csp->addAllowedImageDomain('https://*.opentopomap.org'); + $csp->addAllowedImageDomain('https://*.cartocdn.com'); + $csp->addAllowedImageDomain('https://*.ssl.fastly.net'); + $csp->addAllowedImageDomain('https://*.openstreetmap.se'); + + // default routing engine + $csp->addAllowedConnectDomain('https://*.project-osrm.org'); + $csp->addAllowedConnectDomain('https://api.mapbox.com'); + $csp->addAllowedConnectDomain('https://events.mapbox.com'); + $csp->addAllowedConnectDomain('https://graphhopper.com'); + + $csp->addAllowedChildSrcDomain('blob:'); + $csp->addAllowedWorkerSrcDomain('blob:'); + $csp->addAllowedScriptDomain('https://unpkg.com'); + // allow connections to custom routing engines + $urlKeys = [ + 'osrmBikeURL', + 'osrmCarURL', + 'osrmFootURL', + 'graphhopperURL', 'maplibreStreetStyleURL', 'maplibreStreetStyleAuth' - ]; - foreach ($urlKeys as $key) { - $url = $this->config->getAppValue('maps', $key); - if ($url !== '') { - $scheme = parse_url($url, PHP_URL_SCHEME); - $host = parse_url($url, PHP_URL_HOST); - $port = parse_url($url, PHP_URL_PORT); - $cleanUrl = $scheme . '://' . $host; - if ($port && $port !== '') { - $cleanUrl .= ':' . $port; - } - $csp->addAllowedConnectDomain($cleanUrl); - } - } - //$csp->addAllowedConnectDomain('http://192.168.0.66:5000'); - - // poi images - $csp->addAllowedImageDomain('https://nominatim.openstreetmap.org'); - // search and geocoder - $csp->addAllowedConnectDomain('https://nominatim.openstreetmap.org'); - $response->setContentSecurityPolicy($csp); - } - } + ]; + foreach ($urlKeys as $key) { + $url = $this->config->getAppValue('maps', $key); + if ($url !== '') { + $scheme = parse_url($url, PHP_URL_SCHEME); + $host = parse_url($url, PHP_URL_HOST); + $port = parse_url($url, PHP_URL_PORT); + $cleanUrl = $scheme . '://' . $host; + if ($port && $port !== '') { + $cleanUrl .= ':' . $port; + } + $csp->addAllowedConnectDomain($cleanUrl); + } + } + //$csp->addAllowedConnectDomain('http://192.168.0.66:5000'); + + // poi images + $csp->addAllowedImageDomain('https://nominatim.openstreetmap.org'); + // search and geocoder + $csp->addAllowedConnectDomain('https://nominatim.openstreetmap.org'); + $response->setContentSecurityPolicy($csp); + } + } } diff --git a/lib/Controller/PhotosController.php b/lib/Controller/PhotosController.php index 335775cb0..e9c9d7f21 100644 --- a/lib/Controller/PhotosController.php +++ b/lib/Controller/PhotosController.php @@ -13,41 +13,40 @@ namespace OCA\Maps\Controller; use OC\User\NoUserException; +use OCA\Maps\Service\GeophotoService; +use OCA\Maps\Service\PhotofilesService; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\DataResponse; use OCP\DB\Exception; use OCP\Files\InvalidPathException; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; -use OCP\IRequest; -use OCP\AppFramework\Http\TemplateResponse; -use OCP\AppFramework\Http\DataResponse; -use OCP\AppFramework\Controller; -use OCP\ILogger; -use OCA\Maps\Service\GeophotoService; -use OCA\Maps\Service\PhotofilesService; +use OCP\ILogger; +use OCP\IRequest; class PhotosController extends Controller { - private $userId; - private $geophotoService; - private $photofilesService; - private $logger; + private $userId; + private $geophotoService; + private $photofilesService; + private $logger; private $root; - public function __construct($AppName, - ILogger $logger, - IRequest $request, - GeophotoService $GeophotoService, - PhotofilesService $photofilesService, - IRootFolder $root, - $UserId) { - parent::__construct($AppName, $request); - $this->logger = $logger; - $this->userId = $UserId; - $this->geophotoService = $GeophotoService; - $this->photofilesService = $photofilesService; + public function __construct($AppName, + ILogger $logger, + IRequest $request, + GeophotoService $GeophotoService, + PhotofilesService $photofilesService, + IRootFolder $root, + $UserId) { + parent::__construct($AppName, $request); + $this->logger = $logger; + $this->userId = $UserId; + $this->geophotoService = $GeophotoService; + $this->photofilesService = $photofilesService; $this->root = $root; - } + } /** * @NoAdminRequired @@ -62,17 +61,17 @@ public function __construct($AppName, * @throws NotFoundException * @throws NotPermittedException */ - public function getPhotos($myMapId=null, $respectNoMediaAndNoimage=null, $hideImagesOnCustomMaps=null, $hideImagesInMapsFolder=null): DataResponse { + public function getPhotos($myMapId = null, $respectNoMediaAndNoimage = null, $hideImagesOnCustomMaps = null, $hideImagesInMapsFolder = null): DataResponse { $userFolder = $this->root->getUserFolder($this->userId); - if (is_null($myMapId) || $myMapId === "") { - $result = $this->geophotoService->getAll($this->userId, $userFolder, $respectNoMediaAndNoimage??true, $hideImagesOnCustomMaps??false, $hideImagesInMapsFolder??true); - } else { - $folders = $userFolder->getById($myMapId); - $folder = array_shift($folders); - $result = $this->geophotoService->getAll($this->userId, $folder, $respectNoMediaAndNoimage??true, $hideImagesOnCustomMaps??false, $hideImagesInMapsFolder??false); - } - return new DataResponse($result); - } + if (is_null($myMapId) || $myMapId === '') { + $result = $this->geophotoService->getAll($this->userId, $userFolder, $respectNoMediaAndNoimage ?? true, $hideImagesOnCustomMaps ?? false, $hideImagesInMapsFolder ?? true); + } else { + $folders = $userFolder->getById($myMapId); + $folder = array_shift($folders); + $result = $this->geophotoService->getAll($this->userId, $folder, $respectNoMediaAndNoimage ?? true, $hideImagesOnCustomMaps ?? false, $hideImagesInMapsFolder ?? false); + } + return new DataResponse($result); + } /** * @NoAdminRequired @@ -90,17 +89,17 @@ public function getPhotos($myMapId=null, $respectNoMediaAndNoimage=null, $hideIm * @throws NotFoundException * @throws NotPermittedException */ - public function getNonLocalizedPhotos(?int $myMapId=null, ?string $timezone=null, int $limit=250, int $offset=0, $respectNoMediaAndNoimage=null, $hideImagesOnCustomMaps=null, $hideImagesInMapsFolder=null): DataResponse { + public function getNonLocalizedPhotos(?int $myMapId = null, ?string $timezone = null, int $limit = 250, int $offset = 0, $respectNoMediaAndNoimage = null, $hideImagesOnCustomMaps = null, $hideImagesInMapsFolder = null): DataResponse { $userFolder = $this->root->getUserFolder($this->userId); - if (is_null($myMapId) || $myMapId === "") { - $result = $this->geophotoService->getNonLocalized($this->userId, $userFolder, $respectNoMediaAndNoimage??true, $hideImagesOnCustomMaps??false, $hideImagesInMapsFolder??true, $timezone, $limit, $offset); + if (is_null($myMapId) || $myMapId === '') { + $result = $this->geophotoService->getNonLocalized($this->userId, $userFolder, $respectNoMediaAndNoimage ?? true, $hideImagesOnCustomMaps ?? false, $hideImagesInMapsFolder ?? true, $timezone, $limit, $offset); } else { $folders = $userFolder->getById($myMapId); $folder = array_shift($folders); - $result = $this->geophotoService->getNonLocalized($this->userId, $folder, $respectNoMediaAndNoimage??true, $hideImagesOnCustomMaps??false, $hideImagesInMapsFolder??false, $timezone, $limit, $offset); + $result = $this->geophotoService->getNonLocalized($this->userId, $folder, $respectNoMediaAndNoimage ?? true, $hideImagesOnCustomMaps ?? false, $hideImagesInMapsFolder ?? false, $timezone, $limit, $offset); } - return new DataResponse($result); - } + return new DataResponse($result); + } /** @@ -117,48 +116,48 @@ public function getNonLocalizedPhotos(?int $myMapId=null, ?string $timezone=null * @throws NotPermittedException * @throws InvalidPathException */ - public function placePhotos($paths, $lats, $lngs, bool $directory=false, $myMapId=null, bool $relative=false): DataResponse { + public function placePhotos($paths, $lats, $lngs, bool $directory = false, $myMapId = null, bool $relative = false): DataResponse { $userFolder = $this->root->getUserFolder($this->userId); - if (!is_null($myMapId) and $myMapId !== '') { - // forbid folder placement in my-maps - if ($directory === 'true') { - throw new NotPermittedException(); - } - $folders = $userFolder->getById($myMapId); - $folder = array_shift($folders); - // photo's path is relative to this map's folder => get full path, don't copy - if ($relative === 'true') { - foreach ($paths as $key => $path) { - $photoFile = $folder->get($path); - $paths[$key] = $userFolder->getRelativePath($photoFile->getPath()); - } - } else { - // here the photo path is good, copy it in this map's folder if it's not already there - foreach ($paths as $key => $path) { - $photoFile = $userFolder->get($path); - // is the photo in this map's folder? - if (!$folder->getById($photoFile->getId())) { - $copiedFile = $photoFile->copy($folder->getPath() . '/' . $photoFile->getName()); - $paths[$key] = $userFolder->getRelativePath($copiedFile->getPath()); - } - } - } - } - $result = $this->photofilesService->setPhotosFilesCoords($this->userId, $paths, $lats, $lngs, $directory); - return new DataResponse($result); - } + if (!is_null($myMapId) and $myMapId !== '') { + // forbid folder placement in my-maps + if ($directory === 'true') { + throw new NotPermittedException(); + } + $folders = $userFolder->getById($myMapId); + $folder = array_shift($folders); + // photo's path is relative to this map's folder => get full path, don't copy + if ($relative === 'true') { + foreach ($paths as $key => $path) { + $photoFile = $folder->get($path); + $paths[$key] = $userFolder->getRelativePath($photoFile->getPath()); + } + } else { + // here the photo path is good, copy it in this map's folder if it's not already there + foreach ($paths as $key => $path) { + $photoFile = $userFolder->get($path); + // is the photo in this map's folder? + if (!$folder->getById($photoFile->getId())) { + $copiedFile = $photoFile->copy($folder->getPath() . '/' . $photoFile->getName()); + $paths[$key] = $userFolder->getRelativePath($copiedFile->getPath()); + } + } + } + } + $result = $this->photofilesService->setPhotosFilesCoords($this->userId, $paths, $lats, $lngs, $directory); + return new DataResponse($result); + } /** * @NoAdminRequired * @param $paths * @return DataResponse */ - public function resetPhotosCoords($paths, $myMapId=null): DataResponse { + public function resetPhotosCoords($paths, $myMapId = null): DataResponse { $userFolder = $this->root->getUserFolder($this->userId); - $result = []; - if (sizeof($paths) > 0) { + $result = []; + if (sizeof($paths) > 0) { $result = $this->photofilesService->resetPhotosFilesCoords($this->userId, $paths); - } + } if (!is_null($myMapId) and $myMapId !== '') { foreach ($paths as $key => $path) { $folders = $userFolder->getById($myMapId); @@ -170,8 +169,8 @@ public function resetPhotosCoords($paths, $myMapId=null): DataResponse { } } } - return new DataResponse($result); - } + return new DataResponse($result); + } /** * @NoAdminRequired @@ -180,9 +179,9 @@ public function resetPhotosCoords($paths, $myMapId=null): DataResponse { public function clearCache(): DataResponse { $result = $this->geophotoService->clearCache(); if ($result) { - return new DataResponse("Cache cleared"); + return new DataResponse('Cache cleared'); } else { - return new DataResponse("Failed to clear Cache", 400); + return new DataResponse('Failed to clear Cache', 400); } } diff --git a/lib/Controller/PublicContactsController.php b/lib/Controller/PublicContactsController.php index 5c4cfecfe..2e2bda39b 100644 --- a/lib/Controller/PublicContactsController.php +++ b/lib/Controller/PublicContactsController.php @@ -13,29 +13,27 @@ namespace OCA\Maps\Controller; use OC\Files\Node\Node; +use OCA\DAV\CardDAV\CardDavBackend; +use OCA\Maps\Service\AddressService; +use OCP\AppFramework\Http\DataDisplayResponse; +use OCP\AppFramework\Http\DataResponse; +use OCP\Contacts\IManager; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; +use OCP\IAvatarManager; use OCP\IConfig; +use OCP\IDBConnection; use OCP\IInitialStateService; use OCP\IRequest; -use OCP\IAvatarManager; -use OCP\AppFramework\Http\DataDisplayResponse; -use OCP\AppFramework\Http\DataResponse; -use OCP\IDBConnection; -use OCP\AppFramework\Controller; -use OCP\Contacts\IManager; -use OCA\Maps\Service\AddressService; -use \OCP\DB\QueryBuilder\IQueryBuilder; -use \OCA\DAV\CardDAV\CardDavBackend; use OCP\ISession; use OCP\IURLGenerator; use OCP\IUserManager; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager as ShareManager; -use \Sabre\VObject\Property\Text; -use \Sabre\VObject\Reader; +use Sabre\VObject\Reader; class PublicContactsController extends PublicPageController { protected IManager $contactsManager; @@ -63,20 +61,20 @@ class PublicContactsController extends PublicPageController { * @param IRootFolder $root */ public function __construct($appName, - IRequest $request, - IEventDispatcher $eventDispatcher, - IConfig $config, - IInitialStateService $initialStateService, - IURLGenerator $urlGenerator, - ShareManager $shareManager, - IUserManager $userManager, - ISession $session, - IManager $contactsManager, - IDBConnection $dbconnection, - AddressService $addressService, - CardDavBackend $cdBackend, - IAvatarManager $avatarManager, - IRootFolder $root){ + IRequest $request, + IEventDispatcher $eventDispatcher, + IConfig $config, + IInitialStateService $initialStateService, + IURLGenerator $urlGenerator, + ShareManager $shareManager, + IUserManager $userManager, + ISession $session, + IManager $contactsManager, + IDBConnection $dbconnection, + AddressService $addressService, + CardDavBackend $cdBackend, + IAvatarManager $avatarManager, + IRootFolder $root) { parent::__construct($appName, $request, $eventDispatcher, $config, $initialStateService, $urlGenerator, $shareManager, $userManager, $session); $this->avatarManager = $avatarManager; $this->contactsManager = $contactsManager; @@ -151,13 +149,13 @@ public function getContacts(): DataResponse { $share = $this->getShare(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); - $isReadable = (bool) ($permissions & (1 << 0)); + $isReadable = (bool)($permissions & (1 << 0)); if ($isReadable) { //Fixme add contacts for my-maps $result = []; $files = $folder->search('.vcf'); foreach ($files as $file) { -// $cards = explode("END:VCARD\r\n", $file->getContent()); + // $cards = explode("END:VCARD\r\n", $file->getContent()); $cards = [$file->getContent()]; foreach ($cards as $card) { $vcard = Reader::read($card."END:VCARD\r\n"); @@ -165,7 +163,7 @@ public function getContacts(): DataResponse { $geo = $vcard->GEO; if (is_string($geo->getValue()) && strlen($geo->getValue()) > 1) { $result[] = $this->vCardToArray($permissions, $file, $vcard, $geo->getValue()); - } elseif (is_countable($geo) && count($geo)>0 && is_iterable($geo)) { + } elseif (is_countable($geo) && count($geo) > 0 && is_iterable($geo)) { foreach ($geo as $g) { if (strlen($g->getValue()) > 1) { $result[] = $this->vCardToArray($permissions, $file, $vcard, $g->getValue()); @@ -206,7 +204,7 @@ public function getContacts(): DataResponse { * @throws NotFoundException * @throws \OCP\Files\InvalidPathException */ - private function vCardToArray(int $sharePermissions, Node $file, \Sabre\VObject\Document $vcard, string $geo, ?string $adrtype=null, ?string $adr=null, ?int $fileId = null): array { + private function vCardToArray(int $sharePermissions, Node $file, \Sabre\VObject\Document $vcard, string $geo, ?string $adrtype = null, ?string $adr = null, ?int $fileId = null): array { $FNArray = $vcard->FN ? $vcard->FN->getJsonValue() : []; $fn = array_shift($FNArray); $NArray = $vcard->N ? $vcard->N->getJsonValue() : []; @@ -253,12 +251,10 @@ private function N2FN(string $n): ?string { $spl = explode($n, ';'); if (count($spl) >= 4) { return $spl[3] . ' ' . $spl[1] . ' ' . $spl[0]; - } - else { + } else { return null; } - } - else { + } else { return null; } } diff --git a/lib/Controller/PublicFavoritePageController.php b/lib/Controller/PublicFavoritePageController.php index 71519f839..4aa56b352 100644 --- a/lib/Controller/PublicFavoritePageController.php +++ b/lib/Controller/PublicFavoritePageController.php @@ -39,61 +39,61 @@ use OCP\Util; class PublicFavoritePageController extends PublicShareController { - private $config; - private $logger; - - /* @var FavoriteShareMapper */ - private $favoriteShareMapper; - - public function __construct( - $appName, - IRequest $request, - ISession $session, - IConfig $config, - ILogger $logger, - FavoriteShareMapper $favoriteShareMapper - ) { - parent::__construct($appName, $request, $session); - $this->config = $config; - $this->logger = $logger; - $this->favoriteShareMapper = $favoriteShareMapper; - } - - /** - * @param $token - * - * @return DataResponse|PublicTemplateResponse - * - * @PublicPage - * @NoCSRFRequired - */ - public function sharedFavoritesCategory($token) { - if ($token === '') { - return new DataResponse([], Http::STATUS_BAD_REQUEST); - } - - try { - $share = $this->favoriteShareMapper->findByToken($token); - } catch (DoesNotExistException $e) { - return new DataResponse([], Http::STATUS_NOT_FOUND); - } catch (MultipleObjectsReturnedException $e) { - return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); - } - - Util::addStyle($this->appName, 'merged-public-favorite-share'); - Util::addScript($this->appName, 'maps-publicFavoriteShare'); - - $response = new PublicTemplateResponse('maps', 'public/favorites_index', []); - - $ownerName = OC::$server->getUserManager()->get($share->getOwner())->getDisplayName(); - - $response->setHeaderTitle($share->getCategory()); - $response->setHeaderDetails('shared by ' . $ownerName); - - $this->addCsp($response); - - return $response; - } + private $config; + private $logger; + + /* @var FavoriteShareMapper */ + private $favoriteShareMapper; + + public function __construct( + $appName, + IRequest $request, + ISession $session, + IConfig $config, + ILogger $logger, + FavoriteShareMapper $favoriteShareMapper + ) { + parent::__construct($appName, $request, $session); + $this->config = $config; + $this->logger = $logger; + $this->favoriteShareMapper = $favoriteShareMapper; + } + + /** + * @param $token + * + * @return DataResponse|PublicTemplateResponse + * + * @PublicPage + * @NoCSRFRequired + */ + public function sharedFavoritesCategory($token) { + if ($token === '') { + return new DataResponse([], Http::STATUS_BAD_REQUEST); + } + + try { + $share = $this->favoriteShareMapper->findByToken($token); + } catch (DoesNotExistException $e) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } catch (MultipleObjectsReturnedException $e) { + return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); + } + + Util::addStyle($this->appName, 'merged-public-favorite-share'); + Util::addScript($this->appName, 'maps-publicFavoriteShare'); + + $response = new PublicTemplateResponse('maps', 'public/favorites_index', []); + + $ownerName = OC::$server->getUserManager()->get($share->getOwner())->getDisplayName(); + + $response->setHeaderTitle($share->getCategory()); + $response->setHeaderDetails('shared by ' . $ownerName); + + $this->addCsp($response); + + return $response; + } /** * Get a hash of the password for this share @@ -104,9 +104,9 @@ public function sharedFavoritesCategory($token) { * @return string * @since 14.0.0 */ - protected function getPasswordHash(): string { - return ""; - } + protected function getPasswordHash(): string { + return ''; + } /** * Is the provided token a valid token @@ -116,15 +116,15 @@ protected function getPasswordHash(): string { * @return bool * @since 14.0.0 */ - public function isValidToken(): bool { - try { - $this->favoriteShareMapper->findByToken($this->getToken()); - } catch (DoesNotExistException | MultipleObjectsReturnedException $e) { - return false; - } + public function isValidToken(): bool { + try { + $this->favoriteShareMapper->findByToken($this->getToken()); + } catch (DoesNotExistException|MultipleObjectsReturnedException $e) { + return false; + } - return true; - } + return true; + } /** * Is a share with this token password protected @@ -132,57 +132,57 @@ public function isValidToken(): bool { * @return bool * @since 14.0.0 */ - protected function isPasswordProtected(): bool { - return false; - } + protected function isPasswordProtected(): bool { + return false; + } /** * @param $response * @return void */ private function addCsp($response): void { - if (class_exists('OCP\AppFramework\Http\ContentSecurityPolicy')) { - $csp = new ContentSecurityPolicy(); - // map tiles - $csp->addAllowedImageDomain('https://*.tile.openstreetmap.org'); - $csp->addAllowedImageDomain('https://server.arcgisonline.com'); - $csp->addAllowedImageDomain('https://*.cartocdn.com'); - $csp->addAllowedImageDomain('https://*.opentopomap.org'); - $csp->addAllowedImageDomain('https://*.cartocdn.com'); - $csp->addAllowedImageDomain('https://*.ssl.fastly.net'); - $csp->addAllowedImageDomain('https://*.openstreetmap.se'); - - // default routing engine - $csp->addAllowedConnectDomain('https://*.project-osrm.org'); - $csp->addAllowedConnectDomain('https://api.mapbox.com'); - $csp->addAllowedConnectDomain('https://graphhopper.com'); - // allow connections to custom routing engines - $urlKeys = [ - 'osrmBikeURL', - 'osrmCarURL', - 'osrmFootURL', - 'graphhopperURL' - ]; - foreach ($urlKeys as $key) { - $url = $this->config->getAppValue('maps', $key); - if ($url !== '') { - $scheme = parse_url($url, PHP_URL_SCHEME); - $host = parse_url($url, PHP_URL_HOST); - $port = parse_url($url, PHP_URL_PORT); - $cleanUrl = $scheme . '://' . $host; - if ($port && $port !== '') { - $cleanUrl .= ':' . $port; - } - $csp->addAllowedConnectDomain($cleanUrl); - } - } - //$csp->addAllowedConnectDomain('http://192.168.0.66:5000'); - - // poi images - $csp->addAllowedImageDomain('https://nominatim.openstreetmap.org'); - // search and geocoder - $csp->addAllowedConnectDomain('https://nominatim.openstreetmap.org'); - $response->setContentSecurityPolicy($csp); - } - } + if (class_exists('OCP\AppFramework\Http\ContentSecurityPolicy')) { + $csp = new ContentSecurityPolicy(); + // map tiles + $csp->addAllowedImageDomain('https://*.tile.openstreetmap.org'); + $csp->addAllowedImageDomain('https://server.arcgisonline.com'); + $csp->addAllowedImageDomain('https://*.cartocdn.com'); + $csp->addAllowedImageDomain('https://*.opentopomap.org'); + $csp->addAllowedImageDomain('https://*.cartocdn.com'); + $csp->addAllowedImageDomain('https://*.ssl.fastly.net'); + $csp->addAllowedImageDomain('https://*.openstreetmap.se'); + + // default routing engine + $csp->addAllowedConnectDomain('https://*.project-osrm.org'); + $csp->addAllowedConnectDomain('https://api.mapbox.com'); + $csp->addAllowedConnectDomain('https://graphhopper.com'); + // allow connections to custom routing engines + $urlKeys = [ + 'osrmBikeURL', + 'osrmCarURL', + 'osrmFootURL', + 'graphhopperURL' + ]; + foreach ($urlKeys as $key) { + $url = $this->config->getAppValue('maps', $key); + if ($url !== '') { + $scheme = parse_url($url, PHP_URL_SCHEME); + $host = parse_url($url, PHP_URL_HOST); + $port = parse_url($url, PHP_URL_PORT); + $cleanUrl = $scheme . '://' . $host; + if ($port && $port !== '') { + $cleanUrl .= ':' . $port; + } + $csp->addAllowedConnectDomain($cleanUrl); + } + } + //$csp->addAllowedConnectDomain('http://192.168.0.66:5000'); + + // poi images + $csp->addAllowedImageDomain('https://nominatim.openstreetmap.org'); + // search and geocoder + $csp->addAllowedConnectDomain('https://nominatim.openstreetmap.org'); + $response->setContentSecurityPolicy($csp); + } + } } diff --git a/lib/Controller/PublicFavoritesApiController.php b/lib/Controller/PublicFavoritesApiController.php index d1db521fe..b09fe2d5b 100644 --- a/lib/Controller/PublicFavoritesApiController.php +++ b/lib/Controller/PublicFavoritesApiController.php @@ -36,193 +36,193 @@ use OCP\ISession; class PublicFavoritesApiController extends PublicShareController { - /* @var FavoritesService */ - private $favoritesService; + /* @var FavoritesService */ + private $favoritesService; - /* @var FavoriteShareMapper */ - private $favoriteShareMapper; + /* @var FavoriteShareMapper */ + private $favoriteShareMapper; - public function __construct( - $appName, - IRequest $request, - ISession $session, - FavoritesService $favoritesService, - FavoriteShareMapper $favoriteShareMapper - ) { - parent::__construct($appName, $request, $session); + public function __construct( + $appName, + IRequest $request, + ISession $session, + FavoritesService $favoritesService, + FavoriteShareMapper $favoriteShareMapper + ) { + parent::__construct($appName, $request, $session); - $this->favoriteShareMapper = $favoriteShareMapper; - $this->favoritesService = $favoritesService; - } + $this->favoriteShareMapper = $favoriteShareMapper; + $this->favoritesService = $favoritesService; + } /** * @return string */ - public function getPasswordHash(): string { - return ''; - } + public function getPasswordHash(): string { + return ''; + } /** * @return bool */ - protected function isPasswordProtected(): bool { - return false; - } + protected function isPasswordProtected(): bool { + return false; + } /** * @return bool */ - public function isValidToken(): bool { - try { - $this->favoriteShareMapper->findByToken($this->getToken()); - } catch (DoesNotExistException | MultipleObjectsReturnedException $e) { - return false; - } + public function isValidToken(): bool { + try { + $this->favoriteShareMapper->findByToken($this->getToken()); + } catch (DoesNotExistException|MultipleObjectsReturnedException $e) { + return false; + } - return true; - } + return true; + } /** * @return bool */ - public function canEdit(): bool { - try { - $share = $this->favoriteShareMapper->findByToken($this->getToken()); - } catch (DoesNotExistException | MultipleObjectsReturnedException $e) { - return false; - } - - return $share->getAllowEdits(); - } - - /** - * @PublicPage - * - * @return DataResponse - */ - public function getFavorites(): DataResponse { - try { - $share = $this->favoriteShareMapper->findByToken($this->getToken()); - } catch (DoesNotExistException $e) { - return new DataResponse([], Http::STATUS_NOT_FOUND); - } catch (MultipleObjectsReturnedException $e) { - return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); - } - - $favorites = $this->favoritesService->getFavoritesFromDB($share->getOwner(), 0, $share->getCategory(), false, false, true); - - return new DataResponse([ - 'share' => $share, - 'favorites' => $favorites - ]); - } - -// /** -// * @PublicPage -// * -// * @param $lat -// * @param $lng -// * @param $name -// * @param $comment -// * @param $extensions -// * @return DataResponse -// */ -// public function addFavorite($lat, $lng, $name, $comment, $extensions) -// { -// if (!$this->canEdit()) { -// return new DataResponse('Not authorized to add favorite', Http::STATUS_UNAUTHORIZED); -// } -// -// try { -// $share = $this->favoriteShareMapper->findByToken($this->getToken()); -// } catch (DoesNotExistException $e) { -// return new DataResponse([], Http::STATUS_NOT_FOUND); -// } catch (MultipleObjectsReturnedException $e) { -// return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); -// } -// -// $category = $share->getCategory(); -// -// -// if (is_numeric($lat) && is_numeric($lng)) { -// $favoriteId = $this->favoritesService->addFavoriteToDB($this->userId, $name, $lat, $lng, $category, $comment, $extensions); -// $favorite = $this->favoritesService->getFavoriteFromDB($favoriteId); -// return new DataResponse($favorite); -// } else { -// return new DataResponse('invalid values', 400); -// } -// } - -// /** -// * @PublicPage -// * -// * @param $id -// * @param $lat -// * @param $lng -// * @param $name -// * @param $comment -// * @param $extensions -// * @return DataResponse -// */ -// public function editFavorite($id, $lat, $lng, $name, $comment, $extensions) -// { -// if (!$this->canEdit()) { -// return new DataResponse('Not authorized to edit favorite', Http::STATUS_UNAUTHORIZED); -// } -// -// try { -// $share = $this->favoriteShareMapper->findByToken($this->getToken()); -// } catch (DoesNotExistException $e) { -// return new DataResponse([], Http::STATUS_NOT_FOUND); -// } catch (MultipleObjectsReturnedException $e) { -// return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); -// } -// -// $favorite = $this->favoritesService->getFavoriteFromDB($id, $share->getOwner(), $share->getCategory()); -// -// if ($favorite !== null) { -// if (($lat === null || is_numeric($lat)) && -// ($lng === null || is_numeric($lng)) -// ) { -// $this->favoritesService->editFavoriteInDB($id, $name, $lat, $lng, $favorite['category'], $comment, $extensions); -// $editedFavorite = $this->favoritesService->getFavoriteFromDB($id); -// -// return new DataResponse($editedFavorite); -// } else { -// return new DataResponse('invalid values', 400); -// } -// } else { -// return new DataResponse('no such favorite', 400); -// } -// } - -// /** -// * @PublicPage -// * -// * @param $id -// * @return DataResponse -// */ -// public function deleteFavorite($id) -// { -// if (!$this->canEdit()) { -// return new DataResponse('Not authorized to delete favorite', Http::STATUS_UNAUTHORIZED); -// } -// -// try { -// $share = $this->favoriteShareMapper->findByToken($this->getToken()); -// } catch (DoesNotExistException $e) { -// return new DataResponse([], Http::STATUS_NOT_FOUND); -// } catch (MultipleObjectsReturnedException $e) { -// return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); -// } -// -// $favorite = $this->favoritesService->getFavoriteFromDB($id, $share->getOwner(), $share->getCategory()); -// -// if ($favorite !== null) { -// $this->favoritesService->deleteFavoriteFromDB($id); -// return new DataResponse('deleted'); -// } else { -// return new DataResponse('no such favorite', 400); -// } -// } + public function canEdit(): bool { + try { + $share = $this->favoriteShareMapper->findByToken($this->getToken()); + } catch (DoesNotExistException|MultipleObjectsReturnedException $e) { + return false; + } + + return $share->getAllowEdits(); + } + + /** + * @PublicPage + * + * @return DataResponse + */ + public function getFavorites(): DataResponse { + try { + $share = $this->favoriteShareMapper->findByToken($this->getToken()); + } catch (DoesNotExistException $e) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } catch (MultipleObjectsReturnedException $e) { + return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); + } + + $favorites = $this->favoritesService->getFavoritesFromDB($share->getOwner(), 0, $share->getCategory(), false, false, true); + + return new DataResponse([ + 'share' => $share, + 'favorites' => $favorites + ]); + } + + // /** + // * @PublicPage + // * + // * @param $lat + // * @param $lng + // * @param $name + // * @param $comment + // * @param $extensions + // * @return DataResponse + // */ + // public function addFavorite($lat, $lng, $name, $comment, $extensions) + // { + // if (!$this->canEdit()) { + // return new DataResponse('Not authorized to add favorite', Http::STATUS_UNAUTHORIZED); + // } + // + // try { + // $share = $this->favoriteShareMapper->findByToken($this->getToken()); + // } catch (DoesNotExistException $e) { + // return new DataResponse([], Http::STATUS_NOT_FOUND); + // } catch (MultipleObjectsReturnedException $e) { + // return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); + // } + // + // $category = $share->getCategory(); + // + // + // if (is_numeric($lat) && is_numeric($lng)) { + // $favoriteId = $this->favoritesService->addFavoriteToDB($this->userId, $name, $lat, $lng, $category, $comment, $extensions); + // $favorite = $this->favoritesService->getFavoriteFromDB($favoriteId); + // return new DataResponse($favorite); + // } else { + // return new DataResponse('invalid values', 400); + // } + // } + + // /** + // * @PublicPage + // * + // * @param $id + // * @param $lat + // * @param $lng + // * @param $name + // * @param $comment + // * @param $extensions + // * @return DataResponse + // */ + // public function editFavorite($id, $lat, $lng, $name, $comment, $extensions) + // { + // if (!$this->canEdit()) { + // return new DataResponse('Not authorized to edit favorite', Http::STATUS_UNAUTHORIZED); + // } + // + // try { + // $share = $this->favoriteShareMapper->findByToken($this->getToken()); + // } catch (DoesNotExistException $e) { + // return new DataResponse([], Http::STATUS_NOT_FOUND); + // } catch (MultipleObjectsReturnedException $e) { + // return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); + // } + // + // $favorite = $this->favoritesService->getFavoriteFromDB($id, $share->getOwner(), $share->getCategory()); + // + // if ($favorite !== null) { + // if (($lat === null || is_numeric($lat)) && + // ($lng === null || is_numeric($lng)) + // ) { + // $this->favoritesService->editFavoriteInDB($id, $name, $lat, $lng, $favorite['category'], $comment, $extensions); + // $editedFavorite = $this->favoritesService->getFavoriteFromDB($id); + // + // return new DataResponse($editedFavorite); + // } else { + // return new DataResponse('invalid values', 400); + // } + // } else { + // return new DataResponse('no such favorite', 400); + // } + // } + + // /** + // * @PublicPage + // * + // * @param $id + // * @return DataResponse + // */ + // public function deleteFavorite($id) + // { + // if (!$this->canEdit()) { + // return new DataResponse('Not authorized to delete favorite', Http::STATUS_UNAUTHORIZED); + // } + // + // try { + // $share = $this->favoriteShareMapper->findByToken($this->getToken()); + // } catch (DoesNotExistException $e) { + // return new DataResponse([], Http::STATUS_NOT_FOUND); + // } catch (MultipleObjectsReturnedException $e) { + // return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); + // } + // + // $favorite = $this->favoritesService->getFavoriteFromDB($id, $share->getOwner(), $share->getCategory()); + // + // if ($favorite !== null) { + // $this->favoritesService->deleteFavoriteFromDB($id); + // return new DataResponse('deleted'); + // } else { + // return new DataResponse('no such favorite', 400); + // } + // } } diff --git a/lib/Controller/PublicFavoritesController.php b/lib/Controller/PublicFavoritesController.php index c046b64c7..28de1d763 100644 --- a/lib/Controller/PublicFavoritesController.php +++ b/lib/Controller/PublicFavoritesController.php @@ -13,79 +13,75 @@ namespace OCA\Maps\Controller; -use OCP\EventDispatcher\IEventDispatcher; -use OCP\Files\Folder; -use OCP\Files\NotFoundException; use OCA\Maps\DB\FavoriteShareMapper; use OCA\Maps\Service\FavoritesService; use OCP\App\IAppManager; +use OCP\AppFramework\Http\DataResponse; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\Folder; +use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; +use OCP\IConfig; +use OCP\IDateTimeZone; +use OCP\IGroupManager; use OCP\IInitialStateService; +use OCP\IL10N; +use OCP\ILogger; +use OCP\IRequest; +use OCP\IServerContainer; use OCP\ISession; use OCP\IURLGenerator; +use OCP\IUserManager; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager; -use OCP\IConfig; -use OCP\IUserManager; -use OCP\IGroupManager; -use OCP\ILogger; -use OCP\IServerContainer; -use OCP\AppFramework\Controller; -use OCP\AppFramework\Db\DoesNotExistException; -use OCP\AppFramework\Db\MultipleObjectsReturnedException; -use OCP\AppFramework\Http; -use OCP\AppFramework\Http\DataResponse; -use OCP\IDateTimeZone; -use OCP\IL10N; -use OCP\IRequest; class PublicFavoritesController extends PublicPageController { - private string $appVersion; + private string $appVersion; private IL10N $l; - private FavoritesService $favoritesService; - private IDateTimeZone $dateTimeZone; - private ?string $defaultFavoritsJSON; - protected $appName; + private FavoritesService $favoritesService; + private IDateTimeZone $dateTimeZone; + private ?string $defaultFavoritsJSON; + protected $appName; protected $groupManager; - /* @var FavoriteShareMapper */ - private $favoriteShareMapper; + /* @var FavoriteShareMapper */ + private $favoriteShareMapper; - public function __construct($appName, - IRequest $request, - IServerContainer $serverContainer, - IConfig $config, - IURLGenerator $urlGenerator, - IInitialStateService $initialStateService, - IManager $shareManager, - IAppManager $appManager, - IUserManager $userManager, - IGroupManager $groupManager, - IL10N $l, - ILogger $logger, - FavoritesService $favoritesService, - IDateTimeZone $dateTimeZone, - ISession $session, - FavoriteShareMapper $favoriteShareMapper, - IEventDispatcher $eventDispatcher) { - parent::__construct($appName, $request, $eventDispatcher, $config, $initialStateService, $urlGenerator, $shareManager, $userManager, $session); - $this->favoritesService = $favoritesService; - $this->dateTimeZone = $dateTimeZone; - $this->logger = $logger; - $this->appName = $appName; - $this->appVersion = $config->getAppValue('maps', 'installed_version'); - $this->userManager = $userManager; - $this->groupManager = $groupManager; - $this->l = $l; - $this->config = $config; - $this->shareManager = $shareManager; - $this->favoriteShareMapper = $favoriteShareMapper; - $this->defaultFavoritsJSON = json_encode([ - "type" => "FeatureCollection", - "features"=> [] - ],JSON_PRETTY_PRINT); - } + public function __construct($appName, + IRequest $request, + IServerContainer $serverContainer, + IConfig $config, + IURLGenerator $urlGenerator, + IInitialStateService $initialStateService, + IManager $shareManager, + IAppManager $appManager, + IUserManager $userManager, + IGroupManager $groupManager, + IL10N $l, + ILogger $logger, + FavoritesService $favoritesService, + IDateTimeZone $dateTimeZone, + ISession $session, + FavoriteShareMapper $favoriteShareMapper, + IEventDispatcher $eventDispatcher) { + parent::__construct($appName, $request, $eventDispatcher, $config, $initialStateService, $urlGenerator, $shareManager, $userManager, $session); + $this->favoritesService = $favoritesService; + $this->dateTimeZone = $dateTimeZone; + $this->logger = $logger; + $this->appName = $appName; + $this->appVersion = $config->getAppValue('maps', 'installed_version'); + $this->userManager = $userManager; + $this->groupManager = $groupManager; + $this->l = $l; + $this->config = $config; + $this->shareManager = $shareManager; + $this->favoriteShareMapper = $favoriteShareMapper; + $this->defaultFavoritsJSON = json_encode([ + 'type' => 'FeatureCollection', + 'features' => [] + ], JSON_PRETTY_PRINT); + } /** * Validate the permissions of the share @@ -146,19 +142,19 @@ private function getShareNode() { * @return mixed * @throws NotPermittedException */ - private function getJSONFavoritesFile(\OCP\Files\Folder $folder, $isCreatable): \OCP\Files\Node { - try { - $file = $folder->get('.favorites.json'); - } catch (NotFoundException $e) { + private function getJSONFavoritesFile(\OCP\Files\Folder $folder, $isCreatable): \OCP\Files\Node { + try { + $file = $folder->get('.favorites.json'); + } catch (NotFoundException $e) { if ($isCreatable) { $file = $folder->newFile('.favorites.json', $content = $this->defaultFavoritsJSON); } else { throw new NotPermittedException(); } - } - return $file; - } + } + return $file; + } /** * @PublicPage @@ -166,14 +162,14 @@ private function getJSONFavoritesFile(\OCP\Files\Folder $folder, $isCreatable): * @throws NotFoundException * @throws NotPermittedException */ - public function getFavorites(): DataResponse { + public function getFavorites(): DataResponse { $share = $this->getShare(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); $isCreatable = ($permissions & (1 << 2)) && $folder->isCreatable(); $file = $this->getJSONFavoritesFile($folder, $isCreatable); - $isReadable = (bool) ($permissions & (1 << 0)); + $isReadable = (bool)($permissions & (1 << 0)); if ($isReadable) { $favorites = $this->favoritesService->getFavoritesFromJSON($file); $favorites = array_map(function ($favorite) use ($permissions) { @@ -185,8 +181,8 @@ public function getFavorites(): DataResponse { } else { throw new NotPermittedException(); } - return new DataResponse($favorites); - } + return new DataResponse($favorites); + } /** * @PublicPage @@ -201,8 +197,8 @@ public function getFavorites(): DataResponse { * @throws NotPermittedException * @throws \OCP\Files\InvalidPathException */ - public function addFavorite(?string $name, float $lat, float $lng, ?string $category, ?string $comment, ?string $extensions): DataResponse { - if (is_numeric($lat) && is_numeric($lng)) { + public function addFavorite(?string $name, float $lat, float $lng, ?string $category, ?string $comment, ?string $extensions): DataResponse { + if (is_numeric($lat) && is_numeric($lng)) { $share = $this->getShare(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); @@ -216,11 +212,11 @@ public function addFavorite(?string $name, float $lat, float $lng, ?string $cate } else { throw new NotPermittedException(); } - return new DataResponse($favorite); - } else { - return new DataResponse($this->l->t('Invalid values'), 400); - } - } + return new DataResponse($favorite); + } else { + return new DataResponse($this->l->t('Invalid values'), 400); + } + } /** * @PublicPage @@ -240,8 +236,8 @@ public function addFavorites(array $favorites): DataResponse { if ($isUpdateable) { $favoriteIds = $this->favoritesService->addFavoritesToJSON($file, $favorites); $favoritesAfter = []; - forEach ($this->favoritesService->getFavoritesFromJSON($file) as $favorite) { - if (in_array($favorite['id'],$favoriteIds)) { + foreach ($this->favoritesService->getFavoritesFromJSON($file) as $favorite) { + if (in_array($favorite['id'], $favoriteIds)) { $favorite['isDeletable'] = ($permissions & (1 << 3)) && $favorite['isDeletable']; $favoritesAfter[] = $favorite; } @@ -266,7 +262,7 @@ public function addFavorites(array $favorites): DataResponse { * @throws NotPermittedException * @throws \OCP\Files\InvalidPathException */ - public function editFavorite(int $id, ?string $name, float $lat, float $lng, ?string $category, ?string $comment, ?string $extensions): DataResponse { + public function editFavorite(int $id, ?string $name, float $lat, float $lng, ?string $category, ?string $comment, ?string $extensions): DataResponse { $share = $this->getShare(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); @@ -289,10 +285,10 @@ public function editFavorite(int $id, ?string $name, float $lat, float $lng, ?st } else { return new DataResponse($this->l->t('no such favorite'), 400); } - } else { + } else { throw new NotPermittedException(); } - } + } /** * @PublicPage @@ -303,8 +299,8 @@ public function editFavorite(int $id, ?string $name, float $lat, float $lng, ?st * @throws NotPermittedException * @throws \OCP\Files\InvalidPathException */ - public function renameCategories(array $categories, string $newName): DataResponse { - if (is_array($categories)) { + public function renameCategories(array $categories, string $newName): DataResponse { + if (is_array($categories)) { $share = $this->getShare(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); @@ -312,16 +308,16 @@ public function renameCategories(array $categories, string $newName): DataRespon $file = $this->getJSONFavoritesFile($folder, $isCreatable); $isUpdateable = ($permissions & (1 << 1)) && $file->isUpdateable(); if ($isUpdateable) { - foreach ($categories as $cat) { - $this->favoritesService->renameCategoryInJSON($file, $cat, $newName); - } - } else { + foreach ($categories as $cat) { + $this->favoritesService->renameCategoryInJSON($file, $cat, $newName); + } + } else { throw new NotPermittedException(); } return new DataResponse('RENAMED'); - } + } throw new NotFoundException(); - } + } /** * @PublicPage @@ -331,7 +327,7 @@ public function renameCategories(array $categories, string $newName): DataRespon * @throws NotPermittedException * @throws \OCP\Files\InvalidPathException */ - public function deleteFavorite(int $id): DataResponse { + public function deleteFavorite(int $id): DataResponse { $share = $this->getShare(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); @@ -347,7 +343,7 @@ public function deleteFavorite(int $id): DataResponse { throw new NotPermittedException(); } - } + } /** * @PublicPage @@ -357,20 +353,20 @@ public function deleteFavorite(int $id): DataResponse { * @throws NotPermittedException * @throws \OCP\Files\InvalidPathException */ - public function deleteFavorites(array $ids): DataResponse { + public function deleteFavorites(array $ids): DataResponse { $share = $this->getShare(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); $isCreatable = ($permissions & (1 << 2)) && $folder->isCreatable(); $file = $this->getJSONFavoritesFile($folder, $isCreatable); $isDeleteable = ($permissions & (1 << 3)) && $file->isUpdateable(); - if ($isDeleteable){ - $this->favoritesService->deleteFavoritesFromJSON($file, $ids); - } else { + if ($isDeleteable) { + $this->favoritesService->deleteFavoritesFromJSON($file, $ids); + } else { throw new NotPermittedException(); } - return new DataResponse('DELETED'); - } + return new DataResponse('DELETED'); + } /** * @PublicPage @@ -378,7 +374,7 @@ public function deleteFavorites(array $ids): DataResponse { * @throws NotFoundException * @throws NotPermittedException */ - public function getSharedCategories(): DataResponse { + public function getSharedCategories(): DataResponse { $share = $this->getShare(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); @@ -389,6 +385,6 @@ public function getSharedCategories(): DataResponse { } else { throw new NotPermittedException(); } - return new DataResponse($categories); - } + return new DataResponse($categories); + } } diff --git a/lib/Controller/PublicPageController.php b/lib/Controller/PublicPageController.php index c0de3b387..e347fb714 100644 --- a/lib/Controller/PublicPageController.php +++ b/lib/Controller/PublicPageController.php @@ -18,12 +18,12 @@ use OCA\Viewer\Event\LoadViewer; use OCP\AppFramework\AuthPublicShareController; use OCP\AppFramework\Http\Template\PublicTemplateResponse; +use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\NotFoundException; use OCP\IConfig; +use OCP\IInitialStateService; use OCP\ILogger; use OCP\IRequest; -use OCP\EventDispatcher\IEventDispatcher; -use OCP\IInitialStateService; use OCP\ISession; use OCP\IURLGenerator; use OCP\IUserManager; @@ -39,23 +39,23 @@ class PublicPageController extends AuthPublicShareController { protected ShareManager $shareManager; protected IUserManager $userManager; - public function __construct($AppName, - IRequest $request, - IEventDispatcher $eventDispatcher, - IConfig $config, - IInitialStateService $initialStateService, - IURLGenerator $urlGenerator, - ShareManager $shareManager, - IUserManager $userManager, - ISession $session - ) { - parent::__construct($AppName, $request, $session, $urlGenerator); - $this->eventDispatcher = $eventDispatcher; - $this->config = $config; - $this->initialStateService = $initialStateService; + public function __construct($AppName, + IRequest $request, + IEventDispatcher $eventDispatcher, + IConfig $config, + IInitialStateService $initialStateService, + IURLGenerator $urlGenerator, + ShareManager $shareManager, + IUserManager $userManager, + ISession $session + ) { + parent::__construct($AppName, $request, $session, $urlGenerator); + $this->eventDispatcher = $eventDispatcher; + $this->config = $config; + $this->initialStateService = $initialStateService; $this->shareManager = $shareManager; $this->userManager = $userManager; - } + } public function isValidToken(): bool { try { @@ -123,25 +123,25 @@ private function getShareNode() { return $share->getNode(); } - /** - * @PublicPage - * @NoCSRFRequired - */ - public function showShare(): PublicTemplateResponse { + /** + * @PublicPage + * @NoCSRFRequired + */ + public function showShare(): PublicTemplateResponse { $shareNode = $this->getShareNode(); - $this->eventDispatcher->dispatch(LoadSidebar::class, new LoadSidebar()); - $this->eventDispatcher->dispatch(LoadViewer::class, new LoadViewer()); + $this->eventDispatcher->dispatch(LoadSidebar::class, new LoadSidebar()); + $this->eventDispatcher->dispatch(LoadViewer::class, new LoadViewer()); - $params = []; + $params = []; $params['sharingToken'] = $this->getToken(); - $this->initialStateService->provideInitialState($this->appName, 'photos', $this->config->getAppValue('photos', 'enabled', 'no') === 'yes'); - $response = new PublicTemplateResponse('maps', 'public/main', $params); + $this->initialStateService->provideInitialState($this->appName, 'photos', $this->config->getAppValue('photos', 'enabled', 'no') === 'yes'); + $response = new PublicTemplateResponse('maps', 'public/main', $params); - $this->addCsp($response); + $this->addCsp($response); - return $response; - } + return $response; + } /** * @PublicPage @@ -209,53 +209,53 @@ protected function showIdentificationResult(bool $success = false): PublicTempla * @param $response * @return void */ - private function addCsp($response): void { - if (class_exists('OCP\AppFramework\Http\ContentSecurityPolicy')) { - $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy(); - // map tiles - $csp->addAllowedImageDomain('https://*.tile.openstreetmap.org'); - $csp->addAllowedImageDomain('https://server.arcgisonline.com'); - $csp->addAllowedImageDomain('https://*.cartocdn.com'); - $csp->addAllowedImageDomain('https://*.opentopomap.org'); - $csp->addAllowedImageDomain('https://*.cartocdn.com'); - $csp->addAllowedImageDomain('https://*.ssl.fastly.net'); - $csp->addAllowedImageDomain('https://*.openstreetmap.se'); - - // default routing engine - $csp->addAllowedConnectDomain('https://*.project-osrm.org'); - $csp->addAllowedConnectDomain('https://api.mapbox.com'); - $csp->addAllowedConnectDomain('https://events.mapbox.com'); - $csp->addAllowedConnectDomain('https://graphhopper.com'); - - $csp->addAllowedChildSrcDomain('blob:'); - $csp->addAllowedWorkerSrcDomain('blob:'); - $csp->addAllowedScriptDomain('https://unpkg.com'); - // allow connections to custom routing engines - $urlKeys = [ - 'osrmBikeURL', - 'osrmCarURL', - 'osrmFootURL', - 'graphhopperURL' - ]; - foreach ($urlKeys as $key) { - $url = $this->config->getAppValue('maps', $key); - if ($url !== '') { - $scheme = parse_url($url, PHP_URL_SCHEME); - $host = parse_url($url, PHP_URL_HOST); - $port = parse_url($url, PHP_URL_PORT); - $cleanUrl = $scheme . '://' . $host; - if ($port && $port !== '') { - $cleanUrl .= ':' . $port; - } - $csp->addAllowedConnectDomain($cleanUrl); - } - } - - // poi images - $csp->addAllowedImageDomain('https://nominatim.openstreetmap.org'); - // search and geocoder - $csp->addAllowedConnectDomain('https://nominatim.openstreetmap.org'); - $response->setContentSecurityPolicy($csp); - } - } + private function addCsp($response): void { + if (class_exists('OCP\AppFramework\Http\ContentSecurityPolicy')) { + $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy(); + // map tiles + $csp->addAllowedImageDomain('https://*.tile.openstreetmap.org'); + $csp->addAllowedImageDomain('https://server.arcgisonline.com'); + $csp->addAllowedImageDomain('https://*.cartocdn.com'); + $csp->addAllowedImageDomain('https://*.opentopomap.org'); + $csp->addAllowedImageDomain('https://*.cartocdn.com'); + $csp->addAllowedImageDomain('https://*.ssl.fastly.net'); + $csp->addAllowedImageDomain('https://*.openstreetmap.se'); + + // default routing engine + $csp->addAllowedConnectDomain('https://*.project-osrm.org'); + $csp->addAllowedConnectDomain('https://api.mapbox.com'); + $csp->addAllowedConnectDomain('https://events.mapbox.com'); + $csp->addAllowedConnectDomain('https://graphhopper.com'); + + $csp->addAllowedChildSrcDomain('blob:'); + $csp->addAllowedWorkerSrcDomain('blob:'); + $csp->addAllowedScriptDomain('https://unpkg.com'); + // allow connections to custom routing engines + $urlKeys = [ + 'osrmBikeURL', + 'osrmCarURL', + 'osrmFootURL', + 'graphhopperURL' + ]; + foreach ($urlKeys as $key) { + $url = $this->config->getAppValue('maps', $key); + if ($url !== '') { + $scheme = parse_url($url, PHP_URL_SCHEME); + $host = parse_url($url, PHP_URL_HOST); + $port = parse_url($url, PHP_URL_PORT); + $cleanUrl = $scheme . '://' . $host; + if ($port && $port !== '') { + $cleanUrl .= ':' . $port; + } + $csp->addAllowedConnectDomain($cleanUrl); + } + } + + // poi images + $csp->addAllowedImageDomain('https://nominatim.openstreetmap.org'); + // search and geocoder + $csp->addAllowedConnectDomain('https://nominatim.openstreetmap.org'); + $response->setContentSecurityPolicy($csp); + } + } } diff --git a/lib/Controller/PublicPhotosController.php b/lib/Controller/PublicPhotosController.php index a308c5888..644d33ea2 100644 --- a/lib/Controller/PublicPhotosController.php +++ b/lib/Controller/PublicPhotosController.php @@ -12,20 +12,17 @@ namespace OCA\Maps\Controller; +use OCA\Maps\Service\GeophotoService; +use OCA\Maps\Service\PhotofilesService; +use OCP\AppFramework\Http\DataResponse; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\IConfig; + use OCP\IInitialStateService; use OCP\IRequest; -use OCP\AppFramework\Http\TemplateResponse; -use OCP\AppFramework\Http\DataResponse; -use OCP\AppFramework\Controller; -use OCP\ILogger; - -use OCA\Maps\Service\GeophotoService; -use OCA\Maps\Service\PhotofilesService; use OCP\ISession; use OCP\IURLGenerator; use OCP\IUserManager; @@ -33,27 +30,27 @@ use OCP\Share\IManager as ShareManager; class PublicPhotosController extends PublicPageController { - protected GeophotoService $geophotoService; + protected GeophotoService $geophotoService; protected PhotofilesService $photofilesService; protected IRootFolder $root; - public function __construct($appName, - IRequest $request, - IEventDispatcher $eventDispatcher, - IConfig $config, - IInitialStateService $initialStateService, - IURLGenerator $urlGenerator, - ShareManager $shareManager, - IUserManager $userManager, - ISession $session, - GeophotoService $GeophotoService, - PhotofilesService $photofilesService, - IRootFolder $root) { + public function __construct($appName, + IRequest $request, + IEventDispatcher $eventDispatcher, + IConfig $config, + IInitialStateService $initialStateService, + IURLGenerator $urlGenerator, + ShareManager $shareManager, + IUserManager $userManager, + ISession $session, + GeophotoService $GeophotoService, + PhotofilesService $photofilesService, + IRootFolder $root) { parent::__construct($appName, $request, $eventDispatcher, $config, $initialStateService, $urlGenerator, $shareManager, $userManager, $session); - $this->geophotoService = $GeophotoService; - $this->photofilesService = $photofilesService; + $this->geophotoService = $GeophotoService; + $this->photofilesService = $photofilesService; $this->root = $root; - } + } /** * Validate the permissions of the share @@ -115,17 +112,17 @@ private function getShareNode() { * @throws \OCP\Files\NotPermittedException * @throws \OC\User\NoUserException */ - public function getPhotos(): DataResponse { + public function getPhotos(): DataResponse { $share = $this->getShare(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); - $isReadable = (bool) ($permissions & (1 << 0)); + $isReadable = (bool)($permissions & (1 << 0)); if ($isReadable) { $owner = $share->getShareOwner(); $pre_path = $this->root->getUserFolder($owner)->getPath(); $result = $this->geophotoService->getAll($owner, $folder, true, false, false); $photos = array_map(function ($photo) use ($folder, $permissions, $pre_path) { - $photo_object = (object) $photo; + $photo_object = (object)$photo; $photo_object->isCreatable = ($permissions & (1 << 2)) && $photo['isCreatable']; $photo_object->isUpdateable = ($permissions & (1 << 1)) && $photo['isUpdateable']; $photo_object->isDeletable = ($permissions & (1 << 3)) && $photo['isDeletable']; @@ -137,8 +134,8 @@ public function getPhotos(): DataResponse { throw new NotPermittedException(); } - return new DataResponse($photos); - } + return new DataResponse($photos); + } /** * @PublicPage @@ -148,17 +145,17 @@ public function getPhotos(): DataResponse { * @throws \OCP\Files\InvalidPathException * @throws \OC\User\NoUserException */ - public function getNonLocalizedPhotos(?string $timezone=null, int $limit=250, int $offset=0): DataResponse { + public function getNonLocalizedPhotos(?string $timezone = null, int $limit = 250, int $offset = 0): DataResponse { $share = $this->getShare(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); - $isReadable = (bool) ($permissions & (1 << 0)); + $isReadable = (bool)($permissions & (1 << 0)); if ($isReadable) { $owner = $share->getShareOwner(); $pre_path = $this->root->getUserFolder($owner)->getPath(); $result = $this->geophotoService->getNonLocalized($owner, $folder, true, false, false, $timezone, $limit, $offset); $photos = array_map(function ($photo) use ($folder, $permissions, $pre_path) { - $photo_object = (object) $photo; + $photo_object = (object)$photo; $photo_object->isCreatable = ($permissions & (1 << 2)) && $photo['isCreatable']; $photo_object->isUpdateable = ($permissions & (1 << 1)) && $photo['isUpdateable']; $photo_object->isDeletable = ($permissions & (1 << 3)) && $photo['isDeletable']; @@ -171,7 +168,7 @@ public function getNonLocalizedPhotos(?string $timezone=null, int $limit=250, in } return new DataResponse($photos); - } + } /** * @PublicPage @@ -180,9 +177,9 @@ public function getNonLocalizedPhotos(?string $timezone=null, int $limit=250, in public function clearCache(): DataResponse { $result = $this->geophotoService->clearCache(); if ($result) { - return new DataResponse("Cache cleared"); + return new DataResponse('Cache cleared'); } else { - return new DataResponse("Failed to clear Cache", 400); + return new DataResponse('Failed to clear Cache', 400); } } diff --git a/lib/Controller/PublicTracksController.php b/lib/Controller/PublicTracksController.php index 62e4f5e78..1b2e12679 100644 --- a/lib/Controller/PublicTracksController.php +++ b/lib/Controller/PublicTracksController.php @@ -11,38 +11,28 @@ namespace OCA\Maps\Controller; -use OCP\App\IAppManager; - +use OCA\Maps\Service\TracksService; +use OCP\AppFramework\Http\DataResponse; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; -use OCP\IInitialStateService; -use OCP\ISession; -use OCP\IURLGenerator; use OCP\IConfig; -use \OCP\IL10N; +use OCP\IGroupManager; +use OCP\IInitialStateService; -use OCP\AppFramework\Http; -use OCP\AppFramework\Http\RedirectResponse; -use OCP\AppFramework\Http\ContentSecurityPolicy; +use OCP\IL10N; +use OCP\ILogger; use OCP\IRequest; -use OCP\AppFramework\Http\TemplateResponse; -use OCP\AppFramework\Http\DataResponse; -use OCP\AppFramework\Controller; -use OCP\AppFramework\ApiController; -use OCP\Constants; -use OCP\Share; -use OCP\IUserManager; -use OCP\Share\Exceptions\ShareNotFound; -use OCP\Share\IManager; use OCP\IServerContainer; -use OCP\IGroupManager; -use OCP\ILogger; +use OCP\ISession; +use OCP\IURLGenerator; +use OCP\IUserManager; +use OCP\Share; -use OCA\Maps\Service\TracksService; +use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager as ShareManager; use function OCA\Maps\Helper\remove_utf8_bom; @@ -55,31 +45,31 @@ class PublicTracksController extends PublicPageController { protected IL10N $l; protected ILogger $logger; protected TracksService $tracksService; - protected $appName; + protected $appName; protected IRootFolder $root; - public function __construct($appName, - IRequest $request, - IEventDispatcher $eventDispatcher, - IConfig $config, - IInitialStateService $initialStateService, - IURLGenerator $urlGenerator, - ShareManager $shareManager, - IUserManager $userManager, - ISession $session, - IServerContainer $serverContainer, - IGroupManager $groupManager, - IL10N $l, - ILogger $logger, - TracksService $tracksService, - IRootFolder $root) { + public function __construct($appName, + IRequest $request, + IEventDispatcher $eventDispatcher, + IConfig $config, + IInitialStateService $initialStateService, + IURLGenerator $urlGenerator, + ShareManager $shareManager, + IUserManager $userManager, + ISession $session, + IServerContainer $serverContainer, + IGroupManager $groupManager, + IL10N $l, + ILogger $logger, + TracksService $tracksService, + IRootFolder $root) { parent::__construct($appName, $request, $eventDispatcher, $config, $initialStateService, $urlGenerator, $shareManager, $userManager, $session); - $this->tracksService = $tracksService; - $this->logger = $logger; - $this->groupManager = $groupManager; - $this->l = $l; + $this->tracksService = $tracksService; + $this->logger = $logger; + $this->groupManager = $groupManager; + $this->l = $l; $this->root = $root; - } + } /** * Validate the permissions of the share @@ -141,12 +131,12 @@ private function getShareNode() { * @throws NotPermittedException * @throws \OC\User\NoUserException */ - public function getTracks(): DataResponse { + public function getTracks(): DataResponse { $share = $this->getShare(); - $hideDownload = (bool) $share->getHideDownload(); + $hideDownload = (bool)$share->getHideDownload(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); - $isReadable = (bool) ($permissions & (1 << 0)); + $isReadable = (bool)($permissions & (1 << 0)); if ($isReadable) { $owner = $share->getShareOwner(); $pre_path = $this->root->getUserFolder($owner)->getPath(); @@ -163,8 +153,8 @@ public function getTracks(): DataResponse { } else { throw new NotPermittedException(); } - return new DataResponse($new_tracks); - } + return new DataResponse($new_tracks); + } /** * @PublicPage @@ -178,7 +168,7 @@ public function getTrackContentByFileId($id) { $share = $this->getShare(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); - $isReadable = (bool) ($permissions & (1 << 0)); + $isReadable = (bool)($permissions & (1 << 0)); if (!$isReadable) { throw new NotPermittedException(); } @@ -194,20 +184,17 @@ public function getTrackContentByFileId($id) { if (!$track['metadata'] || $track['etag'] !== $trackFile->getEtag()) { $metadata = $this->tracksService->generateTrackMetadata($trackFile); $this->tracksService->editTrackInDB($track['id'], null, $metadata, $trackFile->getEtag()); - } - else { + } else { $metadata = $track['metadata']; } return new DataResponse([ - 'metadata'=>$metadata, - 'content'=>$trackContent + 'metadata' => $metadata, + 'content' => $trackContent ]); - } - else { + } else { return new DataResponse($this->l->t('Bad file type'), 400); } - } - else { + } else { return new DataResponse($this->l->t('File not found'), 400); } } @@ -219,35 +206,32 @@ public function getTrackContentByFileId($id) { * @throws NotFoundException * @throws \OCP\Files\InvalidPathException */ - public function getTrackFileContent($id): DataResponse { - $track = $this->tracksService->getTrackFromDB($id); - $res = is_null($track) ? null : $this->getShareNode()->getById($track['file_id']); - if (is_array($res) and count($res) > 0) { - $trackFile = array_shift($res); - if ($trackFile->getType() === \OCP\Files\FileInfo::TYPE_FILE) { - $trackContent = remove_utf8_bom($trackFile->getContent()); - // compute metadata if necessary - // first time we get it OR the file changed - if (!$track['metadata'] || $track['etag'] !== $trackFile->getEtag()) { - $metadata = $this->tracksService->generateTrackMetadata($trackFile); - $this->tracksService->editTrackInDB($track['id'], null, $metadata, $trackFile->getEtag()); - } - else { - $metadata = $track['metadata']; - } - return new DataResponse([ - 'metadata'=>$metadata, - 'content'=>$trackContent - ]); - } - else { - return new DataResponse($this->l->t('Bad file type'), 400); - } - } - else { - return new DataResponse($this->l->t('File not found'), 400); - } - } + public function getTrackFileContent($id): DataResponse { + $track = $this->tracksService->getTrackFromDB($id); + $res = is_null($track) ? null : $this->getShareNode()->getById($track['file_id']); + if (is_array($res) and count($res) > 0) { + $trackFile = array_shift($res); + if ($trackFile->getType() === \OCP\Files\FileInfo::TYPE_FILE) { + $trackContent = remove_utf8_bom($trackFile->getContent()); + // compute metadata if necessary + // first time we get it OR the file changed + if (!$track['metadata'] || $track['etag'] !== $trackFile->getEtag()) { + $metadata = $this->tracksService->generateTrackMetadata($trackFile); + $this->tracksService->editTrackInDB($track['id'], null, $metadata, $trackFile->getEtag()); + } else { + $metadata = $track['metadata']; + } + return new DataResponse([ + 'metadata' => $metadata, + 'content' => $trackContent + ]); + } else { + return new DataResponse($this->l->t('Bad file type'), 400); + } + } else { + return new DataResponse($this->l->t('File not found'), 400); + } + } /** * @PublicPage @@ -259,36 +243,35 @@ public function getTrackFileContent($id): DataResponse { * @throws NotFoundException * @throws NotPermittedException */ - public function editTrack($id, $color, $metadata, $etag): DataResponse { + public function editTrack($id, $color, $metadata, $etag): DataResponse { $share = $this->getShare(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); - $isUpdateable = (bool) ($permissions & (1 << 1)); + $isUpdateable = (bool)($permissions & (1 << 1)); if ($isUpdateable) { $owner = $share->getShareOwner(); $track = $this->tracksService->getTrackFromDB($id, $owner); if ($track !== null) { $this->tracksService->editTrackInDB($id, $color, $metadata, $etag); return new DataResponse('EDITED'); - } - else { + } else { return new DataResponse($this->l->t('No such track'), 400); } } else { throw new NotPermittedException(); } - } + } /** * @NoAdminRequired * @param $id * @return DataResponse */ - public function deleteTrack($id): DataResponse { + public function deleteTrack($id): DataResponse { $share = $this->getShare(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); - $isUpdateable = (bool) ($permissions & (1 << 1)); + $isUpdateable = (bool)($permissions & (1 << 1)); //It's allowed to delete a track from the share, if the share is updateable if ($isUpdateable) { $owner = $share->getShareOwner(); @@ -302,6 +285,6 @@ public function deleteTrack($id): DataResponse { } else { throw new NotPermittedException(); } - } + } } diff --git a/lib/Controller/PublicUtilsController.php b/lib/Controller/PublicUtilsController.php index be5319e58..e934f87b4 100644 --- a/lib/Controller/PublicUtilsController.php +++ b/lib/Controller/PublicUtilsController.php @@ -12,21 +12,20 @@ namespace OCA\Maps\Controller; +use OCP\AppFramework\Http\DataResponse; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\GenericFileException; use OCP\Files\InvalidPathException; use OCP\Files\IRootFolder; -use OCP\Files\NotFoundException; +use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; +use OCP\IConfig; use OCP\IInitialStateService; -use OCP\ILogger; +use OCP\IRequest; + use OCP\ISession; use OCP\IURLGenerator; -use OCP\IConfig; - -use OCP\IRequest; -use OCP\AppFramework\Http\DataResponse; use OCP\IUserManager; use OCP\Lock\LockedException; use OCP\Share\Exceptions\ShareNotFound; @@ -36,20 +35,20 @@ class PublicUtilsController extends PublicPageController { protected IRootFolder $root; - public function __construct(string $appName, - IRequest $request, - IConfig $config, - IURLGenerator $urlGenerator, - IInitialStateService $initialStateService, - IUserManager $userManager, - ShareManager $shareManager, - ISession $session, - IRootFolder $root, - IEventDispatcher $eventDispatcher - ) { - parent::__construct($appName, $request, $eventDispatcher, $config, $initialStateService, $urlGenerator, $shareManager, $userManager, $session); + public function __construct(string $appName, + IRequest $request, + IConfig $config, + IURLGenerator $urlGenerator, + IInitialStateService $initialStateService, + IUserManager $userManager, + ShareManager $shareManager, + ISession $session, + IRootFolder $root, + IEventDispatcher $eventDispatcher + ) { + parent::__construct($appName, $request, $eventDispatcher, $config, $initialStateService, $urlGenerator, $shareManager, $userManager, $session); $this->root = $root; - } + } /** * Validate the permissions of the share @@ -110,13 +109,13 @@ private function getShareNode() { * @PublicPage * @return DataResponse */ - public function deleteOptionsValues(): DataResponse { - $keys = $this->config->getUserKeys(Null, 'maps'); - foreach ($keys as $key) { - $this->config->deleteUserValue(Null, 'maps', $key); - } - return new DataResponse(['done'=>1]); - } + public function deleteOptionsValues(): DataResponse { + $keys = $this->config->getUserKeys(null, 'maps'); + foreach ($keys as $key) { + $this->config->deleteUserValue(null, 'maps', $key); + } + return new DataResponse(['done' => 1]); + } /** * Save options values to the DB for current user @@ -130,17 +129,17 @@ public function deleteOptionsValues(): DataResponse { * @throws InvalidPathException * @throws NotPermittedException */ - public function saveOptionValue($options, $myMapId=null): DataResponse { + public function saveOptionValue($options, $myMapId = null): DataResponse { $share = $this->getShare(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); $isCreatable = ($permissions & (1 << 2)) && $folder->isCreatable(); try { - $file=$folder->get(".index.maps"); + $file = $folder->get('.index.maps'); } catch (NotFoundException $e) { if ($isCreatable) { - $file=$folder->newFile(".index.maps", $content = "{}"); + $file = $folder->newFile('.index.maps', $content = '{}'); } else { throw new NotFoundException(); } @@ -151,16 +150,16 @@ public function saveOptionValue($options, $myMapId=null): DataResponse { } try { - $ov = json_decode($file->getContent(),true, 512); + $ov = json_decode($file->getContent(), true, 512); foreach ($options as $key => $value) { $ov[$key] = $value; } $file->putContent(json_encode($ov, JSON_PRETTY_PRINT)); - } catch (LockedException $e){ - return new DataResponse("File is locked", 500); + } catch (LockedException $e) { + return new DataResponse('File is locked', 500); } - return new DataResponse(['done'=>1]); - } + return new DataResponse(['done' => 1]); + } /** * get options values from the config for current user @@ -172,23 +171,23 @@ public function saveOptionValue($options, $myMapId=null): DataResponse { * @throws NotFoundException * @throws NotPermittedException */ - public function getOptionsValues(): DataResponse { - $ov = array(); + public function getOptionsValues(): DataResponse { + $ov = []; $share = $this->getShare(); $permissions = $share->getPermissions(); $folder = $this->getShareNode(); $isCreatable = ($permissions & (1 << 2)) && $folder->isCreatable(); try { - $file=$folder->get(".index.maps"); + $file = $folder->get('.index.maps'); } catch (NotFoundException $e) { if ($isCreatable) { - $file=$folder->newFile(".index.maps", $content = "{}"); + $file = $folder->newFile('.index.maps', $content = '{}'); } else { throw new NotFoundException(); } } - $ov = json_decode($file->getContent(),true, 512); + $ov = json_decode($file->getContent(), true, 512); // Maps content can be read mostly from the folder $ov['isReadable'] = ($permissions & (1 << 0)) && $folder->isReadable(); @@ -201,94 +200,94 @@ public function getOptionsValues(): DataResponse { $ov['isShareable'] = ($permissions & (1 << 4)) && $folder->isShareable(); - // get routing-specific admin settings values - $settingsKeys = [ - 'osrmCarURL', - 'osrmBikeURL', - 'osrmFootURL', - 'osrmDEMO', - 'graphhopperAPIKEY', - 'mapboxAPIKEY', + // get routing-specific admin settings values + $settingsKeys = [ + 'osrmCarURL', + 'osrmBikeURL', + 'osrmFootURL', + 'osrmDEMO', + 'graphhopperAPIKEY', + 'mapboxAPIKEY', 'maplibreStreetStyleURL', 'maplibreStreetStyleAuth', - 'graphhopperURL' - ]; - foreach ($settingsKeys as $k) { - $v = $this->config->getAppValue('maps', $k); - $ov[$k] = $v; - } - return new DataResponse(['values'=>$ov]); - } + 'graphhopperURL' + ]; + foreach ($settingsKeys as $k) { + $v = $this->config->getAppValue('maps', $k); + $ov[$k] = $v; + } + return new DataResponse(['values' => $ov]); + } - /** - * get content of mapbox traffic style - * @PublicPage + /** + * get content of mapbox traffic style + * @PublicPage * - * @return DataResponse - */ - public function getTrafficStyle(): DataResponse { - $style = [ - 'version' => 8, - 'name' => 'Mapbox Traffic tileset v1', - 'sources' => [ - 'mapbox-traffic' => [ - 'url' => 'mapbox://mapbox.mapbox-traffic-v1', - 'type' => 'vector' - ] - ], - 'layers' => [ - [ - 'id' => 'traffic', - 'source' => 'mapbox-traffic', - 'source-layer' => 'traffic', - 'type' => 'line', - 'paint' => [ - 'line-width' => 2.0, - 'line-color' => [ - 'case', - [ - '==', - 'low', - [ - 'get', - 'congestion' - ] - ], - '#00ff00', - [ - '==', - 'moderate', - [ - 'get', - 'congestion' - ] - ], - '#ffad00', - [ - '==', - 'heavy', - [ - 'get', - 'congestion' - ] - ], - '#ff0000', - [ - '==', - 'severe', - [ - 'get', - 'congestion' - ] - ], - '#b43b71', - '#000000' - ] - ] - ] - ] - ]; - return new DataResponse($style); - } + * @return DataResponse + */ + public function getTrafficStyle(): DataResponse { + $style = [ + 'version' => 8, + 'name' => 'Mapbox Traffic tileset v1', + 'sources' => [ + 'mapbox-traffic' => [ + 'url' => 'mapbox://mapbox.mapbox-traffic-v1', + 'type' => 'vector' + ] + ], + 'layers' => [ + [ + 'id' => 'traffic', + 'source' => 'mapbox-traffic', + 'source-layer' => 'traffic', + 'type' => 'line', + 'paint' => [ + 'line-width' => 2.0, + 'line-color' => [ + 'case', + [ + '==', + 'low', + [ + 'get', + 'congestion' + ] + ], + '#00ff00', + [ + '==', + 'moderate', + [ + 'get', + 'congestion' + ] + ], + '#ffad00', + [ + '==', + 'heavy', + [ + 'get', + 'congestion' + ] + ], + '#ff0000', + [ + '==', + 'severe', + [ + 'get', + 'congestion' + ] + ], + '#b43b71', + '#000000' + ] + ] + ] + ] + ]; + return new DataResponse($style); + } } diff --git a/lib/Controller/RoutingController.php b/lib/Controller/RoutingController.php index 0e1b47a70..f511c382c 100644 --- a/lib/Controller/RoutingController.php +++ b/lib/Controller/RoutingController.php @@ -14,79 +14,71 @@ use OCA\Maps\Service\TracksService; use OCP\App\IAppManager; -use OCP\IURLGenerator; -use OCP\IConfig; -use \OCP\IL10N; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\DataResponse; -use OCP\AppFramework\Http; -use OCP\AppFramework\Http\RedirectResponse; -use OCP\AppFramework\Http\ContentSecurityPolicy; -use OCP\IRequest; -use OCP\AppFramework\Http\TemplateResponse; -use OCP\AppFramework\Http\DataResponse; -use OCP\AppFramework\Controller; -use OCP\AppFramework\ApiController; -use OCP\Constants; -use OCP\Share; +use OCP\IConfig; use OCP\IDateTimeZone; -use OCP\IUserManager; -use OCP\Share\IManager; -use OCP\IServerContainer; use OCP\IGroupManager; +use OCP\IL10N; use OCP\ILogger; +use OCP\IRequest; +use OCP\IServerContainer; +use OCP\IUserManager; +use OCP\Share\IManager; class RoutingController extends Controller { - private $userId; - private $userfolder; - private $config; - private $appVersion; - private $shareManager; - private $userManager; - private $groupManager; - private $dbtype; - private $dbdblquotes; - private $defaultDeviceId; - private $l; - private $logger; - private $dateTimeZone; + private $userId; + private $userfolder; + private $config; + private $appVersion; + private $shareManager; + private $userManager; + private $groupManager; + private $dbtype; + private $dbdblquotes; + private $defaultDeviceId; + private $l; + private $logger; + private $dateTimeZone; private $tracksService; - protected $appName; + protected $appName; - public function __construct($AppName, - IRequest $request, - IServerContainer $serverContainer, - IConfig $config, - IManager $shareManager, - IAppManager $appManager, - IUserManager $userManager, - IGroupManager $groupManager, - IL10N $l, - ILogger $logger, - IDateTimeZone $dateTimeZone, - TracksService $tracksService, - $UserId){ - parent::__construct($AppName, $request); - $this->logger = $logger; - $this->dateTimeZone = $dateTimeZone; - $this->appName = $AppName; - $this->appVersion = $config->getAppValue('maps', 'installed_version'); - $this->userId = $UserId; - $this->userManager = $userManager; - $this->groupManager = $groupManager; - $this->l = $l; - $this->dbtype = $config->getSystemValue('dbtype'); - // IConfig object - $this->config = $config; - if ($UserId !== '' and $UserId !== null and $serverContainer !== null){ - // path of user files folder relative to DATA folder - $this->userfolder = $serverContainer->getUserFolder($UserId); - } - $this->shareManager = $shareManager; + public function __construct($AppName, + IRequest $request, + IServerContainer $serverContainer, + IConfig $config, + IManager $shareManager, + IAppManager $appManager, + IUserManager $userManager, + IGroupManager $groupManager, + IL10N $l, + ILogger $logger, + IDateTimeZone $dateTimeZone, + TracksService $tracksService, + $UserId) { + parent::__construct($AppName, $request); + $this->logger = $logger; + $this->dateTimeZone = $dateTimeZone; + $this->appName = $AppName; + $this->appVersion = $config->getAppValue('maps', 'installed_version'); + $this->userId = $UserId; + $this->userManager = $userManager; + $this->groupManager = $groupManager; + $this->l = $l; + $this->dbtype = $config->getSystemValue('dbtype'); + // IConfig object + $this->config = $config; + if ($UserId !== '' and $UserId !== null and $serverContainer !== null) { + // path of user files folder relative to DATA folder + $this->userfolder = $serverContainer->getUserFolder($UserId); + } + $this->shareManager = $shareManager; $this->tracksService = $tracksService; - } + } /** * @NoAdminRequired @@ -99,9 +91,9 @@ public function __construct($AppName, * @throws \OCP\Files\NotFoundException * @throws \OCP\Files\NotPermittedException */ - public function exportRoute($type, $coords, $name, $totDist, $totTime, $myMapId=null): DataResponse { - // create /Maps directory if necessary - $userFolder = $this->userfolder; + public function exportRoute($type, $coords, $name, $totDist, $totTime, $myMapId = null): DataResponse { + // create /Maps directory if necessary + $userFolder = $this->userfolder; if (is_null($myMapId) || $myMapId === '') { if (!$userFolder->nodeExists('/Maps')) { $userFolder->newFolder('Maps'); @@ -111,13 +103,11 @@ public function exportRoute($type, $coords, $name, $totDist, $totTime, $myMapId= if ($mapsFolder->getType() !== \OCP\Files\FileInfo::TYPE_FOLDER) { $response = new DataResponse($this->l->t('/Maps is not a directory'), 400); return $response; - } - else if (!$mapsFolder->isCreatable()) { + } elseif (!$mapsFolder->isCreatable()) { $response = new DataResponse($this->l->t('/Maps directory is not writeable'), 400); return $response; } - } - else { + } else { $response = new DataResponse($this->l->t('Impossible to create /Maps directory'), 400); return $response; } @@ -134,52 +124,52 @@ public function exportRoute($type, $coords, $name, $totDist, $totTime, $myMapId= } } - $filename = $name.'.gpx'; - if ($mapsFolder->nodeExists($filename)) { - $mapsFolder->get($filename)->delete(); - } + $filename = $name.'.gpx'; + if ($mapsFolder->nodeExists($filename)) { + $mapsFolder->get($filename)->delete(); + } if ($mapsFolder->nodeExists($filename.'.tmp')) { $mapsFolder->get($filename.'.tmp')->delete(); } - $file = $mapsFolder->newFile($filename.'tmp'); - $fileHandler = $file->fopen('w'); + $file = $mapsFolder->newFile($filename.'tmp'); + $fileHandler = $file->fopen('w'); - $dt = new \DateTime(); - $date = $dt->format('Y-m-d\TH:i:s\Z'); + $dt = new \DateTime(); + $date = $dt->format('Y-m-d\TH:i:s\Z'); - $gpxHeader = ' + $gpxHeader = ' '.$name.' '; - fwrite($fileHandler, $gpxHeader."\n"); + fwrite($fileHandler, $gpxHeader."\n"); - if ($type === 'route') { - fwrite($fileHandler, ' '."\n"); - fwrite($fileHandler, ' '.$name.''."\n"); - foreach ($coords as $ll) { - $line = ' ' . "\n"; - fwrite($fileHandler, $line); - } - fwrite($fileHandler, ' '."\n"); - } elseif ($type === 'track') { - fwrite($fileHandler, ' '."\n"); - fwrite($fileHandler, ' '.$name.''."\n"); - fwrite($fileHandler, ' '."\n"); - foreach ($coords as $ll) { - $line = ' ' . "\n"; - fwrite($fileHandler, $line); - } - fwrite($fileHandler, ' '."\n"); - fwrite($fileHandler, ' '."\n"); - } - fwrite($fileHandler, ''."\n"); - fclose($fileHandler); + if ($type === 'route') { + fwrite($fileHandler, ' '."\n"); + fwrite($fileHandler, ' '.$name.''."\n"); + foreach ($coords as $ll) { + $line = ' ' . "\n"; + fwrite($fileHandler, $line); + } + fwrite($fileHandler, ' '."\n"); + } elseif ($type === 'track') { + fwrite($fileHandler, ' '."\n"); + fwrite($fileHandler, ' '.$name.''."\n"); + fwrite($fileHandler, ' '."\n"); + foreach ($coords as $ll) { + $line = ' ' . "\n"; + fwrite($fileHandler, $line); + } + fwrite($fileHandler, ' '."\n"); + fwrite($fileHandler, ' '."\n"); + } + fwrite($fileHandler, ''."\n"); + fclose($fileHandler); $file->touch(); - $file->move(substr($file->getPath(), 0, -3)); + $file->move(substr($file->getPath(), 0, -3)); $track = $this->tracksService->getTrackByFileIDFromDB($file->getId(), $this->userId); - return new DataResponse($track); - } + return new DataResponse($track); + } } diff --git a/lib/Controller/TracksController.php b/lib/Controller/TracksController.php index c9c153eb3..c268fcbf2 100644 --- a/lib/Controller/TracksController.php +++ b/lib/Controller/TracksController.php @@ -11,78 +11,70 @@ namespace OCA\Maps\Controller; -use OCP\App\IAppManager; +use OCA\Maps\Service\TracksService; -use OCP\IURLGenerator; -use OCP\IConfig; -use \OCP\IL10N; +use OCP\App\IAppManager; +use OCP\AppFramework\Controller; -use OCP\AppFramework\Http; -use OCP\AppFramework\Http\RedirectResponse; -use OCP\AppFramework\Http\ContentSecurityPolicy; -use OCP\IRequest; -use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Http\DataResponse; -use OCP\AppFramework\Controller; -use OCP\AppFramework\ApiController; -use OCP\Constants; -use OCP\Share; -use OCP\IUserManager; -use OCP\Share\IManager; -use OCP\IServerContainer; +use OCP\IConfig; use OCP\IGroupManager; +use OCP\IL10N; use OCP\ILogger; +use OCP\IRequest; +use OCP\IServerContainer; +use OCP\IUserManager; -use OCA\Maps\Service\TracksService; +use OCP\Share\IManager; use function OCA\Maps\Helper\remove_utf8_bom; class TracksController extends Controller { - private $userId; - private $userfolder; - private $config; - private $appVersion; - private $shareManager; - private $userManager; - private $groupManager; - private $dbtype; - private $dbdblquotes; - private $l; - private $logger; - private $tracksService; - protected $appName; - - public function __construct($AppName, - IRequest $request, - IServerContainer $serverContainer, - IConfig $config, - IManager $shareManager, - IAppManager $appManager, - IUserManager $userManager, - IGroupManager $groupManager, - IL10N $l, - ILogger $logger, - TracksService $tracksService, - $UserId){ - parent::__construct($AppName, $request); - $this->tracksService = $tracksService; - $this->logger = $logger; - $this->appName = $AppName; - $this->appVersion = $config->getAppValue('maps', 'installed_version'); - $this->userId = $UserId; - $this->userManager = $userManager; - $this->groupManager = $groupManager; - $this->l = $l; - $this->dbtype = $config->getSystemValue('dbtype'); - $this->config = $config; - if ($UserId !== '' and $UserId !== null and $serverContainer !== null){ - $this->userfolder = $serverContainer->getUserFolder($UserId); - } - $this->shareManager = $shareManager; - } + private $userId; + private $userfolder; + private $config; + private $appVersion; + private $shareManager; + private $userManager; + private $groupManager; + private $dbtype; + private $dbdblquotes; + private $l; + private $logger; + private $tracksService; + protected $appName; + + public function __construct($AppName, + IRequest $request, + IServerContainer $serverContainer, + IConfig $config, + IManager $shareManager, + IAppManager $appManager, + IUserManager $userManager, + IGroupManager $groupManager, + IL10N $l, + ILogger $logger, + TracksService $tracksService, + $UserId) { + parent::__construct($AppName, $request); + $this->tracksService = $tracksService; + $this->logger = $logger; + $this->appName = $AppName; + $this->appVersion = $config->getAppValue('maps', 'installed_version'); + $this->userId = $UserId; + $this->userManager = $userManager; + $this->groupManager = $groupManager; + $this->l = $l; + $this->dbtype = $config->getSystemValue('dbtype'); + $this->config = $config; + if ($UserId !== '' and $UserId !== null and $serverContainer !== null) { + $this->userfolder = $serverContainer->getUserFolder($UserId); + } + $this->shareManager = $shareManager; + } /** * @NoAdminRequired @@ -90,16 +82,16 @@ public function __construct($AppName, * @throws \OCP\Files\InvalidPathException * @throws \OCP\Files\NotFoundException */ - public function getTracks($myMapId=null): DataResponse { - if (is_null($myMapId) || $myMapId === '') { - $tracks = $this->tracksService->getTracksFromDB($this->userId, $this->userfolder, true, false, true); - } else { - $folders = $this->userfolder->getById($myMapId); - $folder = array_shift($folders); - $tracks = $this->tracksService->getTracksFromDB($this->userId, $folder, true, false, false); - } - return new DataResponse($tracks); - } + public function getTracks($myMapId = null): DataResponse { + if (is_null($myMapId) || $myMapId === '') { + $tracks = $this->tracksService->getTracksFromDB($this->userId, $this->userfolder, true, false, true); + } else { + $folders = $this->userfolder->getById($myMapId); + $folder = array_shift($folders); + $tracks = $this->tracksService->getTracksFromDB($this->userId, $folder, true, false, false); + } + return new DataResponse($tracks); + } /** * @NoAdminRequired @@ -116,20 +108,17 @@ public function getTrackContentByFileId($id) { if (!$track['metadata'] || $track['etag'] !== $trackFile->getEtag()) { $metadata = $this->tracksService->generateTrackMetadata($trackFile); $this->tracksService->editTrackInDB($track['id'], null, $metadata, $trackFile->getEtag()); - } - else { + } else { $metadata = $track['metadata']; } return new DataResponse([ - 'metadata'=>$metadata, - 'content'=>$trackContent + 'metadata' => $metadata, + 'content' => $trackContent ]); - } - else { + } else { return new DataResponse($this->l->t('Bad file type'), 400); } - } - else { + } else { return new DataResponse($this->l->t('File not found'), 400); } } @@ -141,35 +130,32 @@ public function getTrackContentByFileId($id) { * @throws \OCP\Files\InvalidPathException * @throws \OCP\Files\NotFoundException */ - public function getTrackFileContent($id): DataResponse { - $track = $this->tracksService->getTrackFromDB($id); - $res = is_null($track) ? null : $this->userfolder->getById($track['file_id']); - if (is_array($res) and count($res) > 0) { - $trackFile = $res[0]; - if ($trackFile->getType() === \OCP\Files\FileInfo::TYPE_FILE) { - $trackContent = remove_utf8_bom($trackFile->getContent()); - // compute metadata if necessary - // first time we get it OR the file changed - if (!$track['metadata'] || $track['etag'] !== $trackFile->getEtag()) { - $metadata = $this->tracksService->generateTrackMetadata($trackFile); - $this->tracksService->editTrackInDB($track['id'], null, $metadata, $trackFile->getEtag()); - } - else { - $metadata = $track['metadata']; - } - return new DataResponse([ - 'metadata'=>$metadata, - 'content'=>$trackContent - ]); - } - else { - return new DataResponse($this->l->t('Bad file type'), 400); - } - } - else { - return new DataResponse($this->l->t('File not found'), 400); - } - } + public function getTrackFileContent($id): DataResponse { + $track = $this->tracksService->getTrackFromDB($id); + $res = is_null($track) ? null : $this->userfolder->getById($track['file_id']); + if (is_array($res) and count($res) > 0) { + $trackFile = $res[0]; + if ($trackFile->getType() === \OCP\Files\FileInfo::TYPE_FILE) { + $trackContent = remove_utf8_bom($trackFile->getContent()); + // compute metadata if necessary + // first time we get it OR the file changed + if (!$track['metadata'] || $track['etag'] !== $trackFile->getEtag()) { + $metadata = $this->tracksService->generateTrackMetadata($trackFile); + $this->tracksService->editTrackInDB($track['id'], null, $metadata, $trackFile->getEtag()); + } else { + $metadata = $track['metadata']; + } + return new DataResponse([ + 'metadata' => $metadata, + 'content' => $trackContent + ]); + } else { + return new DataResponse($this->l->t('Bad file type'), 400); + } + } else { + return new DataResponse($this->l->t('File not found'), 400); + } + } /** * @NoAdminRequired @@ -179,31 +165,29 @@ public function getTrackFileContent($id): DataResponse { * @param $etag * @return DataResponse */ - public function editTrack($id, $color, $metadata, $etag): DataResponse { - $track = $this->tracksService->getTrackFromDB($id, $this->userId); - if ($track !== null) { - $this->tracksService->editTrackInDB($id, $color, $metadata, $etag); - return new DataResponse('EDITED'); - } - else { - return new DataResponse($this->l->t('No such track'), 400); - } - } + public function editTrack($id, $color, $metadata, $etag): DataResponse { + $track = $this->tracksService->getTrackFromDB($id, $this->userId); + if ($track !== null) { + $this->tracksService->editTrackInDB($id, $color, $metadata, $etag); + return new DataResponse('EDITED'); + } else { + return new DataResponse($this->l->t('No such track'), 400); + } + } /** * @NoAdminRequired * @param $id * @return DataResponse */ - public function deleteTrack($id): DataResponse { - $track = $this->tracksService->getTrackFromDB($id, $this->userId); - if ($track !== null) { - $this->tracksService->deleteTrackFromDB($id); - return new DataResponse('DELETED'); - } - else { - return new DataResponse($this->l->t('No such track'), 400); - } - } + public function deleteTrack($id): DataResponse { + $track = $this->tracksService->getTrackFromDB($id, $this->userId); + if ($track !== null) { + $this->tracksService->deleteTrackFromDB($id); + return new DataResponse('DELETED'); + } else { + return new DataResponse($this->l->t('No such track'), 400); + } + } } diff --git a/lib/Controller/UtilsController.php b/lib/Controller/UtilsController.php index c7285acb8..1afbfc427 100644 --- a/lib/Controller/UtilsController.php +++ b/lib/Controller/UtilsController.php @@ -12,44 +12,39 @@ namespace OCA\Maps\Controller; -use League\Flysystem\FileNotFoundException; -use OCP\Files\IRootFolder; -use OCP\Files\NotFoundException; use OCP\App\IAppManager; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\ContentSecurityPolicy; -use OCP\IURLGenerator; -use OCP\IConfig; +use OCP\AppFramework\Http\DataResponse; -use OCP\AppFramework\Http; -use OCP\AppFramework\Http\RedirectResponse; -use OCP\AppFramework\Http\ContentSecurityPolicy; +use OCP\Files\IRootFolder; +use OCP\Files\NotFoundException; +use OCP\IConfig; use OCP\IRequest; -use OCP\AppFramework\Http\DataResponse; -use OCP\AppFramework\Controller; use OCP\Lock\LockedException; -use PhpParser\JsonDecoder; class UtilsController extends Controller { - private $userId; - private $config; + private $userId; + private $config; private $root; - public function __construct($AppName, - IRequest $request, - IConfig $config, - IAppManager $appManager, - IRootFolder $root, - $UserId){ - parent::__construct($AppName, $request); + public function __construct($AppName, + IRequest $request, + IConfig $config, + IAppManager $appManager, + IRootFolder $root, + $UserId) { + parent::__construct($AppName, $request); $this->root = $root; - $this->userId = $UserId; - // IConfig object - $this->config = $config; - } + $this->userId = $UserId; + // IConfig object + $this->config = $config; + } /** * Delete user options @@ -57,13 +52,13 @@ public function __construct($AppName, * @NoAdminRequired * @return DataResponse */ - public function deleteOptionsValues(): DataResponse { - $keys = $this->config->getUserKeys($this->userId, 'maps'); - foreach ($keys as $key) { - $this->config->deleteUserValue($this->userId, 'maps', $key); - } - return new DataResponse(['done'=>1]); - } + public function deleteOptionsValues(): DataResponse { + $keys = $this->config->getUserKeys($this->userId, 'maps'); + foreach ($keys as $key) { + $this->config->deleteUserValue($this->userId, 'maps', $key); + } + return new DataResponse(['done' => 1]); + } /** * Save options values to the DB for current user @@ -73,32 +68,32 @@ public function deleteOptionsValues(): DataResponse { * @return DataResponse * @throws \OCP\PreConditionNotMetException */ - public function saveOptionValue($options, $myMapId=null): DataResponse { - if( is_null($myMapId) || $myMapId==="") { - foreach ($options as $key => $value) { - $this->config->setUserValue($this->userId, 'maps', $key, $value); - } - } else { + public function saveOptionValue($options, $myMapId = null): DataResponse { + if (is_null($myMapId) || $myMapId === '') { + foreach ($options as $key => $value) { + $this->config->setUserValue($this->userId, 'maps', $key, $value); + } + } else { $userFolder = $this->root->getUserFolder($this->userId); - $folders = $userFolder->getById($myMapId); - $folder = array_shift($folders); - try { - $file=$folder->get(".index.maps"); - } catch (NotFoundException $e) { - $file=$folder->newFile(".index.maps", $content = "{}"); - } - try { - $ov = json_decode($file->getContent(),true, 512); - foreach ($options as $key => $value) { - $ov[$key] = $value; - } - $file->putContent(json_encode($ov, JSON_PRETTY_PRINT)); - } catch (LockedException $e){ - return new DataResponse("File is locked", 500); - } - } - return new DataResponse(['done'=>1]); - } + $folders = $userFolder->getById($myMapId); + $folder = array_shift($folders); + try { + $file = $folder->get('.index.maps'); + } catch (NotFoundException $e) { + $file = $folder->newFile('.index.maps', $content = '{}'); + } + try { + $ov = json_decode($file->getContent(), true, 512); + foreach ($options as $key => $value) { + $ov[$key] = $value; + } + $file->putContent(json_encode($ov, JSON_PRETTY_PRINT)); + } catch (LockedException $e) { + return new DataResponse('File is locked', 500); + } + } + return new DataResponse(['done' => 1]); + } /** * get options values from the config for current user @@ -106,31 +101,31 @@ public function saveOptionValue($options, $myMapId=null): DataResponse { * @NoAdminRequired * @return DataResponse */ - public function getOptionsValues($myMapId=null): DataResponse { - $ov = array(); + public function getOptionsValues($myMapId = null): DataResponse { + $ov = []; - if( is_null($myMapId) || $myMapId==="") { - // get all user values - $keys = $this->config->getUserKeys($this->userId, 'maps'); - foreach ($keys as $key) { - $value = $this->config->getUserValue($this->userId, 'maps', $key); - $ov[$key] = $value; - } + if (is_null($myMapId) || $myMapId === '') { + // get all user values + $keys = $this->config->getUserKeys($this->userId, 'maps'); + foreach ($keys as $key) { + $value = $this->config->getUserValue($this->userId, 'maps', $key); + $ov[$key] = $value; + } $ov['isCreatable'] = true; $ov['isDeletable'] = false; $ov['isReadable'] = true; $ov['isUpdateable'] = true; $ov['isShareable'] = true; - } else { + } else { $userFolder = $this->root->getUserFolder($this->userId); - $folders = $userFolder->getById($myMapId); - $folder = array_shift($folders); - try { - $file=$folder->get(".index.maps"); - } catch (NotFoundException $e) { - $file=$folder->newFile(".index.maps", $content = "{}"); - } - $ov = json_decode($file->getContent(),true, 512); + $folders = $userFolder->getById($myMapId); + $folder = array_shift($folders); + try { + $file = $folder->get('.index.maps'); + } catch (NotFoundException $e) { + $file = $folder->newFile('.index.maps', $content = '{}'); + } + $ov = json_decode($file->getContent(), true, 512); $ov['isCreatable'] = $folder->isCreatable(); //We can delete the map by deleting the folder or the .index.maps file $ov['isDeletable'] = $folder->isDeletable() || $file->isDeletable(); @@ -140,26 +135,26 @@ public function getOptionsValues($myMapId=null): DataResponse { $ov['isUpdateable'] = $file->isUpdateable(); // Share map by sharing the folder $ov['isShareable'] = $folder->isShareable(); - } + } - // get routing-specific admin settings values - $settingsKeys = [ - 'osrmCarURL', - 'osrmBikeURL', - 'osrmFootURL', - 'osrmDEMO', - 'graphhopperAPIKEY', - 'mapboxAPIKEY', + // get routing-specific admin settings values + $settingsKeys = [ + 'osrmCarURL', + 'osrmBikeURL', + 'osrmFootURL', + 'osrmDEMO', + 'graphhopperAPIKEY', + 'mapboxAPIKEY', 'maplibreStreetStyleURL', 'maplibreStreetStyleAuth', - 'graphhopperURL' - ]; - foreach ($settingsKeys as $k) { - $v = $this->config->getAppValue('maps', $k); - $ov[$k] = $v; - } - return new DataResponse(['values'=>$ov]); - } + 'graphhopperURL' + ]; + foreach ($settingsKeys as $k) { + $v = $this->config->getAppValue('maps', $k); + $ov[$k] = $v; + } + return new DataResponse(['values' => $ov]); + } /** * set routing settings @@ -167,101 +162,101 @@ public function getOptionsValues($myMapId=null): DataResponse { * @param $values * @return DataResponse */ - public function setRoutingSettings($values): DataResponse { - $acceptedKeys = [ - 'osrmCarURL', - 'osrmBikeURL', - 'osrmFootURL', - 'osrmDEMO', - 'graphhopperAPIKEY', - 'mapboxAPIKEY', + public function setRoutingSettings($values): DataResponse { + $acceptedKeys = [ + 'osrmCarURL', + 'osrmBikeURL', + 'osrmFootURL', + 'osrmDEMO', + 'graphhopperAPIKEY', + 'mapboxAPIKEY', 'maplibreStreetStyleURL', 'maplibreStreetStyleAuth', - 'graphhopperURL' - ]; - foreach ($values as $k=>$v) { - if (in_array($k, $acceptedKeys)) { - $this->config->setAppValue('maps', $k, $v); - } - } - $response = new DataResponse('DONE'); - $csp = new ContentSecurityPolicy(); - $csp->addAllowedImageDomain('*') - ->addAllowedMediaDomain('*') - ->addAllowedConnectDomain('*'); - $response->setContentSecurityPolicy($csp); - return $response; - } + 'graphhopperURL' + ]; + foreach ($values as $k => $v) { + if (in_array($k, $acceptedKeys)) { + $this->config->setAppValue('maps', $k, $v); + } + } + $response = new DataResponse('DONE'); + $csp = new ContentSecurityPolicy(); + $csp->addAllowedImageDomain('*') + ->addAllowedMediaDomain('*') + ->addAllowedConnectDomain('*'); + $response->setContentSecurityPolicy($csp); + return $response; + } - /** - * get content of mapbox traffic style - * @NoAdminRequired - * @NoCSRFRequired - * - * @return DataResponse - */ - public function getTrafficStyle(): DataResponse { - $style = [ - 'version' => 8, - 'name' => 'Mapbox Traffic tileset v1', - 'sources' => [ - 'mapbox-traffic' => [ - 'url' => 'mapbox://mapbox.mapbox-traffic-v1', - 'type' => 'vector' - ] - ], - 'layers' => [ - [ - 'id' => 'traffic', - 'source' => 'mapbox-traffic', - 'source-layer' => 'traffic', - 'type' => 'line', - 'paint' => [ - 'line-width' => 2.0, - 'line-color' => [ - 'case', - [ - '==', - 'low', - [ - 'get', - 'congestion' - ] - ], - '#00ff00', - [ - '==', - 'moderate', - [ - 'get', - 'congestion' - ] - ], - '#ffad00', - [ - '==', - 'heavy', - [ - 'get', - 'congestion' - ] - ], - '#ff0000', - [ - '==', - 'severe', - [ - 'get', - 'congestion' - ] - ], - '#b43b71', - '#000000' - ] - ] - ] - ] - ]; - return new DataResponse($style); - } + /** + * get content of mapbox traffic style + * @NoAdminRequired + * @NoCSRFRequired + * + * @return DataResponse + */ + public function getTrafficStyle(): DataResponse { + $style = [ + 'version' => 8, + 'name' => 'Mapbox Traffic tileset v1', + 'sources' => [ + 'mapbox-traffic' => [ + 'url' => 'mapbox://mapbox.mapbox-traffic-v1', + 'type' => 'vector' + ] + ], + 'layers' => [ + [ + 'id' => 'traffic', + 'source' => 'mapbox-traffic', + 'source-layer' => 'traffic', + 'type' => 'line', + 'paint' => [ + 'line-width' => 2.0, + 'line-color' => [ + 'case', + [ + '==', + 'low', + [ + 'get', + 'congestion' + ] + ], + '#00ff00', + [ + '==', + 'moderate', + [ + 'get', + 'congestion' + ] + ], + '#ffad00', + [ + '==', + 'heavy', + [ + 'get', + 'congestion' + ] + ], + '#ff0000', + [ + '==', + 'severe', + [ + 'get', + 'congestion' + ] + ], + '#b43b71', + '#000000' + ] + ] + ] + ] + ]; + return new DataResponse($style); + } } diff --git a/lib/DB/DeviceShare.php b/lib/DB/DeviceShare.php index 6455f04b6..b6dfa8496 100644 --- a/lib/DB/DeviceShare.php +++ b/lib/DB/DeviceShare.php @@ -37,15 +37,15 @@ * @method string setTimestampTo(int $timestampTo) */ class DeviceShare extends Entity { - public $token; - public $deviceId; + public $token; + public $deviceId; public $timestampFrom; public $timestampTo; - public function __construct() { - $this->addType('token', 'string'); - $this->addType('deviceId', 'int'); + public function __construct() { + $this->addType('token', 'string'); + $this->addType('deviceId', 'int'); $this->addType('timestampFrom', 'int'); $this->addType('timestampTo', 'int'); - } + } } diff --git a/lib/DB/DeviceShareMapper.php b/lib/DB/DeviceShareMapper.php index cb2acfa28..32e04b2f0 100644 --- a/lib/DB/DeviceShareMapper.php +++ b/lib/DB/DeviceShareMapper.php @@ -36,36 +36,35 @@ use OCP\IDBConnection; use OCP\Security\ISecureRandom; - class DeviceShareMapper extends QBMapper { - /* @var ISecureRandom */ - private $secureRandom; + /* @var ISecureRandom */ + private $secureRandom; private $root; - public function __construct(IDBConnection $db, ISecureRandom $secureRandom, IRootFolder $root) { - parent::__construct($db, 'maps_device_shares'); + public function __construct(IDBConnection $db, ISecureRandom $secureRandom, IRootFolder $root) { + parent::__construct($db, 'maps_device_shares'); - $this->secureRandom = $secureRandom; + $this->secureRandom = $secureRandom; $this->root = $root; - } - - /** - * @param string $token - * @return Entity|null - * @throws DoesNotExistException - * @throws MultipleObjectsReturnedException - */ - public function findByToken($token) { - $qb = $this->db->getQueryBuilder(); - - $qb->select("*") - ->from($this->getTableName()) - ->where( - $qb->expr()->eq('token', $qb->createNamedParameter($token, IQueryBuilder::PARAM_STR)) - ); - - return $this->findEntity($qb); - } + } + + /** + * @param string $token + * @return Entity|null + * @throws DoesNotExistException + * @throws MultipleObjectsReturnedException + */ + public function findByToken($token) { + $qb = $this->db->getQueryBuilder(); + + $qb->select('*') + ->from($this->getTableName()) + ->where( + $qb->expr()->eq('token', $qb->createNamedParameter($token, IQueryBuilder::PARAM_STR)) + ); + + return $this->findEntity($qb); + } /** * @param string[] $token @@ -75,7 +74,7 @@ public function findByToken($token) { public function findByTokens($tokens) { $qb = $this->db->getQueryBuilder(); - $qb->select("*") + $qb->select('*') ->from($this->getTableName()) ->where( $qb->expr()->in('token', $qb->createNamedParameter($tokens, IQueryBuilder::PARAM_STR)) @@ -84,44 +83,44 @@ public function findByTokens($tokens) { return $this->findEntities($qb); } - /** - * @param $deviceId + /** + * @param $deviceId * @param $timestampFrom * @param $timestampTo - * @return Entity - */ - public function create($deviceId, $timestampFrom, $timestampTo): Entity { - $token = $this->secureRandom->generate( - Constants::TOKEN_LENGTH, - ISecureRandom::CHAR_HUMAN_READABLE - ); - - $newShare = new DeviceShare(); - $newShare->setToken($token); - $newShare->setDeviceId($deviceId); - $newShare->setTimestampFrom($timestampFrom); + * @return Entity + */ + public function create($deviceId, $timestampFrom, $timestampTo): Entity { + $token = $this->secureRandom->generate( + Constants::TOKEN_LENGTH, + ISecureRandom::CHAR_HUMAN_READABLE + ); + + $newShare = new DeviceShare(); + $newShare->setToken($token); + $newShare->setDeviceId($deviceId); + $newShare->setTimestampFrom($timestampFrom); $newShare->setTimestampTo($timestampTo); - return $this->insert($newShare); - } + return $this->insert($newShare); + } - /** - * @param $deviceId - * @return Entity[] - * @throws DoesNotExistException - */ - public function findByDeviceId($deviceId) { - $qb = $this->db->getQueryBuilder(); + /** + * @param $deviceId + * @return Entity[] + * @throws DoesNotExistException + */ + public function findByDeviceId($deviceId) { + $qb = $this->db->getQueryBuilder(); - $qb->select('*') - ->from($this->getTableName()) - ->where( - $qb->expr()->eq('device_id', $qb->createNamedParameter($deviceId, IQueryBuilder::PARAM_INT)) - ); + $qb->select('*') + ->from($this->getTableName()) + ->where( + $qb->expr()->eq('device_id', $qb->createNamedParameter($deviceId, IQueryBuilder::PARAM_INT)) + ); - return $this->findEntities($qb); - } + return $this->findEntities($qb); + } /** * @param $deviceIds @@ -189,10 +188,10 @@ public function removeByMapIdAndDeviceId($userId, $mapId, $deviceId) { * @throws Exception * @throws MultipleObjectsReturnedException */ - public function findById($id) { + public function findById($id) { $qb = $this->db->getQueryBuilder(); - $qb->select("*") + $qb->select('*') ->from($this->getTableName()) ->where( $qb->expr()->eq('id', $qb->createNamedParameter($id)) @@ -215,19 +214,19 @@ public function removeById($id) { return true; } - /** - * @param $deviceId - * @return bool - */ - public function removeAllByDeviceId($deviceId) { - try { - $entities = $this->findByDeviceId($deviceId); + /** + * @param $deviceId + * @return bool + */ + public function removeAllByDeviceId($deviceId) { + try { + $entities = $this->findByDeviceId($deviceId); foreach ($entities as $entity) { $this->delete($entity); } - } catch (DoesNotExistException) { - return false; - } - return true; - } + } catch (DoesNotExistException) { + return false; + } + return true; + } } diff --git a/lib/DB/FavoriteShare.php b/lib/DB/FavoriteShare.php index 66c91e75c..b07de4073 100644 --- a/lib/DB/FavoriteShare.php +++ b/lib/DB/FavoriteShare.php @@ -37,15 +37,15 @@ * @method string setOwner(string $owner) */ class FavoriteShare extends Entity { - public $owner; - public $token; - public $category; - public $allowEdits = false; + public $owner; + public $token; + public $category; + public $allowEdits = false; - public function __construct() { - $this->addType('owner', 'string'); - $this->addType('token', 'string'); - $this->addType('category', 'string'); - $this->addType('allowEdits', 'boolean'); - } + public function __construct() { + $this->addType('owner', 'string'); + $this->addType('token', 'string'); + $this->addType('category', 'string'); + $this->addType('allowEdits', 'boolean'); + } } diff --git a/lib/DB/FavoriteShareMapper.php b/lib/DB/FavoriteShareMapper.php index 485dc28e0..54753412c 100644 --- a/lib/DB/FavoriteShareMapper.php +++ b/lib/DB/FavoriteShareMapper.php @@ -35,71 +35,70 @@ use OCP\IDBConnection; use OCP\Security\ISecureRandom; - class FavoriteShareMapper extends QBMapper { - /* @var ISecureRandom */ - private $secureRandom; + /* @var ISecureRandom */ + private $secureRandom; private $root; - public function __construct(IDBConnection $db, ISecureRandom $secureRandom, IRootFolder $root) { - parent::__construct($db, 'maps_favorite_shares'); + public function __construct(IDBConnection $db, ISecureRandom $secureRandom, IRootFolder $root) { + parent::__construct($db, 'maps_favorite_shares'); - $this->secureRandom = $secureRandom; + $this->secureRandom = $secureRandom; $this->root = $root; - } - - /** - * @param $token - * @return Entity|null - * @throws DoesNotExistException - * @throws MultipleObjectsReturnedException - */ - public function findByToken($token) { - $qb = $this->db->getQueryBuilder(); - - $qb->select("*") - ->from($this->getTableName()) - ->where( - $qb->expr()->eq('token', $qb->createNamedParameter($token, IQueryBuilder::PARAM_STR)) - ); - - return $this->findEntity($qb); - } - - /** - * @param $owner - * @param $category - * @return Entity - */ - public function create($owner, $category) { - $token = $this->secureRandom->generate( - Constants::TOKEN_LENGTH, - ISecureRandom::CHAR_HUMAN_READABLE - ); - - $newShare = new FavoriteShare(); - $newShare->setToken($token); - $newShare->setCategory($category); - $newShare->setOwner($owner); - - return $this->insert($newShare); - } - - /** - * @param $owner - * @return array|Entity[] - */ - public function findAllByOwner($owner) { - $qb = $this->db->getQueryBuilder(); - - $qb->select("*") - ->from($this->getTableName()) - ->where( - $qb->expr()->eq('owner', $qb->createNamedParameter($owner, IQueryBuilder::PARAM_STR)) - ); - - return $this->findEntities($qb); - } + } + + /** + * @param $token + * @return Entity|null + * @throws DoesNotExistException + * @throws MultipleObjectsReturnedException + */ + public function findByToken($token) { + $qb = $this->db->getQueryBuilder(); + + $qb->select('*') + ->from($this->getTableName()) + ->where( + $qb->expr()->eq('token', $qb->createNamedParameter($token, IQueryBuilder::PARAM_STR)) + ); + + return $this->findEntity($qb); + } + + /** + * @param $owner + * @param $category + * @return Entity + */ + public function create($owner, $category) { + $token = $this->secureRandom->generate( + Constants::TOKEN_LENGTH, + ISecureRandom::CHAR_HUMAN_READABLE + ); + + $newShare = new FavoriteShare(); + $newShare->setToken($token); + $newShare->setCategory($category); + $newShare->setOwner($owner); + + return $this->insert($newShare); + } + + /** + * @param $owner + * @return array|Entity[] + */ + public function findAllByOwner($owner) { + $qb = $this->db->getQueryBuilder(); + + $qb->select('*') + ->from($this->getTableName()) + ->where( + $qb->expr()->eq('owner', $qb->createNamedParameter($owner, IQueryBuilder::PARAM_STR)) + ); + + return $this->findEntities($qb); + } /** * @param $userId @@ -128,39 +127,39 @@ public function findAllByMapId($userId, $mapId) { * @return mixed * @throws NotFoundException */ - public function findAllByFolder($folder, $isCreatable=true) { + public function findAllByFolder($folder, $isCreatable = true) { try { - $file=$folder->get(".favorite_shares.json"); + $file = $folder->get('.favorite_shares.json'); } catch (NotFoundException $e) { if ($isCreatable) { - $file=$folder->newFile(".favorite_shares.json", $content = '[]'); + $file = $folder->newFile('.favorite_shares.json', $content = '[]'); } else { throw new NotFoundException(); } } - return json_decode($file->getContent(),true); + return json_decode($file->getContent(), true); } - /** - * @param $owner - * @param $category - * @return Entity - * @throws DoesNotExistException - * @throws MultipleObjectsReturnedException - */ - public function findByOwnerAndCategory($owner, $category) { - $qb = $this->db->getQueryBuilder(); - - $qb->select('*') - ->from($this->getTableName()) - ->where( - $qb->expr()->eq('category', $qb->createNamedParameter($category, IQueryBuilder::PARAM_STR)) - )->andWhere( - $qb->expr()->eq('owner', $qb->createNamedParameter($owner, IQueryBuilder::PARAM_STR)) - ); - - return $this->findEntity($qb); - } + /** + * @param $owner + * @param $category + * @return Entity + * @throws DoesNotExistException + * @throws MultipleObjectsReturnedException + */ + public function findByOwnerAndCategory($owner, $category) { + $qb = $this->db->getQueryBuilder(); + + $qb->select('*') + ->from($this->getTableName()) + ->where( + $qb->expr()->eq('category', $qb->createNamedParameter($category, IQueryBuilder::PARAM_STR)) + )->andWhere( + $qb->expr()->eq('owner', $qb->createNamedParameter($owner, IQueryBuilder::PARAM_STR)) + ); + + return $this->findEntity($qb); + } /** * @param $userId @@ -193,14 +192,14 @@ public function removeByMapIdAndCategory($userId, $mapId, $category) { return $deleted; } try { - $file=$folder->get(".favorite_shares.json"); + $file = $folder->get('.favorite_shares.json'); } catch (NotFoundException $e) { - $file=$folder->newFile(".favorite_shares.json", $content = '[]'); + $file = $folder->newFile('.favorite_shares.json', $content = '[]'); } - $data = json_decode($file->getContent(),true); + $data = json_decode($file->getContent(), true); foreach ($data as $share) { - $c = $share["category"]; - if($c === $category) { + $c = $share['category']; + if ($c === $category) { $deleted = $share; } else { $shares[] = $share; @@ -210,39 +209,39 @@ public function removeByMapIdAndCategory($userId, $mapId, $category) { return $deleted; } - /** - * @param $owner - * @param $category - * @return Entity|null - */ - public function findOrCreateByOwnerAndCategory($owner, $category) { - /* @var Entity */ - $entity = null; - - try { - $entity = $this->findByOwnerAndCategory($owner, $category); - } catch (DoesNotExistException $e) { - $entity = $this->create($owner, $category); - } catch (MultipleObjectsReturnedException $e) { - } - - return $entity; - } - - /** - * @param $owner - * @param $category - * @return bool - */ - public function removeByOwnerAndCategory($owner, $category) { - try { - $entity = $this->findByOwnerAndCategory($owner, $category); - } catch (DoesNotExistException | MultipleObjectsReturnedException $e) { - return false; - } - - $this->delete($entity); - - return true; - } + /** + * @param $owner + * @param $category + * @return Entity|null + */ + public function findOrCreateByOwnerAndCategory($owner, $category) { + /* @var Entity */ + $entity = null; + + try { + $entity = $this->findByOwnerAndCategory($owner, $category); + } catch (DoesNotExistException $e) { + $entity = $this->create($owner, $category); + } catch (MultipleObjectsReturnedException $e) { + } + + return $entity; + } + + /** + * @param $owner + * @param $category + * @return bool + */ + public function removeByOwnerAndCategory($owner, $category) { + try { + $entity = $this->findByOwnerAndCategory($owner, $category); + } catch (DoesNotExistException|MultipleObjectsReturnedException $e) { + return false; + } + + $this->delete($entity); + + return true; + } } diff --git a/lib/DB/Geophoto.php b/lib/DB/Geophoto.php index 29dd81ae9..e2133738a 100644 --- a/lib/DB/Geophoto.php +++ b/lib/DB/Geophoto.php @@ -16,16 +16,16 @@ class Geophoto extends Entity { - protected $fileId; - protected $lat; - protected $lng; - protected $dateTaken; - protected $userId; + protected $fileId; + protected $lat; + protected $lng; + protected $dateTaken; + protected $userId; - public function __construct() { - $this->addType('fileId', 'integer'); - $this->addType('lat', 'float'); - $this->addType('lng', 'float'); - $this->addType('dateTaken', 'integer'); - } + public function __construct() { + $this->addType('fileId', 'integer'); + $this->addType('lat', 'float'); + $this->addType('lng', 'float'); + $this->addType('dateTaken', 'integer'); + } } diff --git a/lib/DB/GeophotoMapper.php b/lib/DB/GeophotoMapper.php index e151a658c..1b9a2b0e0 100644 --- a/lib/DB/GeophotoMapper.php +++ b/lib/DB/GeophotoMapper.php @@ -10,19 +10,17 @@ * @copyright Piotr Bator 2017 */ - namespace OCA\Maps\DB; +namespace OCA\Maps\DB; -use OCP\AppFramework\Db\DoesNotExistException; -use OCP\AppFramework\Db\MultipleObjectsReturnedException; +use OCP\AppFramework\Db\QBMapper; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; -use OCP\AppFramework\Db\QBMapper; class GeophotoMapper extends QBMapper { - public function __construct(IDBConnection $db) { - parent::__construct($db, 'maps_photos'); - } + public function __construct(IDBConnection $db) { + parent::__construct($db, 'maps_photos'); + } /** * @param $id @@ -31,17 +29,17 @@ public function __construct(IDBConnection $db) { * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException * @throws \OCP\DB\Exception */ - public function find($id) { + public function find($id) { $qb = $this->db->getQueryBuilder(); - $qb->select("*") + $qb->select('*') ->from($this->getTableName()) ->where( $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_STR)) ); return $this->findEntity($qb); - } + } /** * @param $fileId @@ -51,10 +49,10 @@ public function find($id) { * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException * @throws \OCP\DB\Exception */ - public function findByFileIdUserId($fileId, $userId) { + public function findByFileIdUserId($fileId, $userId) { $qb = $this->db->getQueryBuilder(); - $qb->select("*") + $qb->select('*') ->from($this->getTableName()) ->where( $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) @@ -63,7 +61,7 @@ public function findByFileIdUserId($fileId, $userId) { ); return $this->findEntity($qb); - } + } /** * @param $fileId @@ -75,7 +73,7 @@ public function findByFileIdUserId($fileId, $userId) { public function findByFileId($fileId) { $qb = $this->db->getQueryBuilder(); - $qb->select("*") + $qb->select('*') ->from($this->getTableName()) ->where( $qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_STR)) @@ -91,10 +89,10 @@ public function findByFileId($fileId) { * @return array|\OCP\AppFramework\Db\Entity[] * @throws \OCP\DB\Exception */ - public function findAll($userId, $limit=null, $offset=null) { + public function findAll($userId, $limit = null, $offset = null) { $qb = $this->db->getQueryBuilder(); - $qb->select("*") + $qb->select('*') ->from($this->getTableName()) ->where( $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) @@ -110,7 +108,7 @@ public function findAll($userId, $limit=null, $offset=null) { $qb->setMaxResults($limit); } return $this->findEntities($qb); - } + } /** * @param $userId @@ -119,10 +117,10 @@ public function findAll($userId, $limit=null, $offset=null) { * @return array|\OCP\AppFramework\Db\Entity[] * @throws \OCP\DB\Exception */ - public function findAllNonLocalized($userId, $limit=null, $offset=null) { + public function findAllNonLocalized($userId, $limit = null, $offset = null) { $qb = $this->db->getQueryBuilder(); - $qb->select("*") + $qb->select('*') ->from($this->getTableName()) ->where( $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) @@ -139,14 +137,14 @@ public function findAllNonLocalized($userId, $limit=null, $offset=null) { $qb->setMaxResults($limit); } return array_reverse($this->findEntities($qb)); - } + } /** * @param $fileId * @return int * @throws \OCP\DB\Exception */ - public function deleteByFileId($fileId) { + public function deleteByFileId($fileId) { $qb = $this->db->getQueryBuilder(); $qb->delete($this->getTableName()) @@ -155,7 +153,7 @@ public function deleteByFileId($fileId) { ); return $qb->executeStatement(); - } + } /** * @param $fileId @@ -163,7 +161,7 @@ public function deleteByFileId($fileId) { * @return int * @throws \OCP\DB\Exception */ - public function deleteByFileIdUserId($fileId, $userId) { + public function deleteByFileIdUserId($fileId, $userId) { $qb = $this->db->getQueryBuilder(); $qb->delete($this->getTableName()) @@ -173,14 +171,14 @@ public function deleteByFileIdUserId($fileId, $userId) { $qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_STR)) ); return $qb->executeStatement(); - } + } /** * @param $userId * @return int * @throws \OCP\DB\Exception */ - public function deleteAll($userId) { + public function deleteAll($userId) { $qb = $this->db->getQueryBuilder(); $qb->delete($this->getTableName()) @@ -188,7 +186,7 @@ public function deleteAll($userId) { $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) ); return $qb->executeStatement(); - } + } /** * @param $fileId @@ -197,7 +195,7 @@ public function deleteAll($userId) { * @return int * @throws \OCP\DB\Exception */ - public function updateByFileId($fileId, $lat, $lng) { + public function updateByFileId($fileId, $lat, $lng) { $qb = $this->db->getQueryBuilder(); $qb->update($this->getTableName()) @@ -205,7 +203,7 @@ public function updateByFileId($fileId, $lat, $lng) { ->set('lng', $qb->createNamedParameter($lng)) ->where($qb->expr()->eq('file_id', $qb->createNamedParameter($fileId))); - return $qb->executeStatement(); - } + return $qb->executeStatement(); + } } diff --git a/lib/Helper/ExifDataInvalidException.php b/lib/Helper/ExifDataInvalidException.php index 3a92b05e7..6f50b335d 100644 --- a/lib/Helper/ExifDataInvalidException.php +++ b/lib/Helper/ExifDataInvalidException.php @@ -14,6 +14,5 @@ /** * Class GeoPhotoException */ -class ExifDataInvalidException extends \Exception -{ +class ExifDataInvalidException extends \Exception { } diff --git a/lib/Helper/ExifDataNoLocationException.php b/lib/Helper/ExifDataNoLocationException.php index 80ceed8fa..8b158c5da 100644 --- a/lib/Helper/ExifDataNoLocationException.php +++ b/lib/Helper/ExifDataNoLocationException.php @@ -14,6 +14,5 @@ /** * Class GeoPhotoException */ -class ExifDataNoLocationException extends \Exception -{ +class ExifDataNoLocationException extends \Exception { } diff --git a/lib/Helper/ExifGeoData.php b/lib/Helper/ExifGeoData.php index 91a2f01bb..1c330e84f 100644 --- a/lib/Helper/ExifGeoData.php +++ b/lib/Helper/ExifGeoData.php @@ -24,7 +24,7 @@ //PHP 7 polyfill if (!function_exists('str_contains')) { function str_contains(string $haystack, string $needle): bool { - return '' === $needle || false !== strpos($haystack, $needle); + return $needle === '' || strpos($haystack, $needle) !== false; } } @@ -35,370 +35,355 @@ function str_contains(string $haystack, string $needle): bool { * @property-read ?float $lng * @property-read ?int $dateTaken */ -class ExifGeoData - extends \stdClass - implements \JsonSerializable -{ - /** - * Mime type regex - */ - private const SUPPORTED_MIMETYPES = 'image\/(jpe?g|tiff)'; - - /** - * Exif Latitude attribute names - */ - private const LATITUDE_REF = 'GPSLatitudeRef'; - private const LATITUDE = 'GPSLatitude'; - - /** - * Exif Longitude attribute names - */ - private const LONGITUDE_REF = 'GPSLongitudeRef'; - private const LONGITUDE = 'GPSLongitude'; - - /** - * Exif Timestamp attribute name - */ - private const TIMESTAMP = 'DateTimeOriginal'; - - /** - * Coordinate modulo - * Modulo between degree, minute, second - */ - private const COORDINATE_MODULO = 60; - - - /** - * Regex to extract date components from exif parameter - */ - private const EXIF_TIME_REGEX = '(?[0-9]{4})\:(?[0-9]{2})\:(?[0-9]{2}) (?[0-9]{2})\:(?[0-9]{2})\:(?[0-9]{2})'; - - /** - * @var int|null - */ - private $timestamp = null; - - /** - * @var float|null - */ - private $latitude = null; - - /** - * @var float|null - */ - private $longitude = null; - - /** - * @var bool|null - */ - private $is_valid = null; - - /** - * @var ?array - */ - protected $exif_data = null; - - /** - * @param string $path - * - * @return array|null - * @throws PelInvalidArgumentException - */ - protected static function get_exif_data_array(string $path) : array{ - if( function_exists('exif_read_data') ) { - $data = @exif_read_data($path, null, true); - if ($data && isset($data['EXIF']) && isset($data['EXIF'][self::LATITUDE]) && isset($data['EXIF'][self::LONGITUDE])) { - return $data['EXIF']; - } elseif ($data && isset($data['GPS']) && isset($data['GPS'][self::LATITUDE]) && isset($data['GPS'][self::LONGITUDE])) { +class ExifGeoData extends \stdClass implements \JsonSerializable { + /** + * Mime type regex + */ + private const SUPPORTED_MIMETYPES = 'image\/(jpe?g|tiff)'; + + /** + * Exif Latitude attribute names + */ + private const LATITUDE_REF = 'GPSLatitudeRef'; + private const LATITUDE = 'GPSLatitude'; + + /** + * Exif Longitude attribute names + */ + private const LONGITUDE_REF = 'GPSLongitudeRef'; + private const LONGITUDE = 'GPSLongitude'; + + /** + * Exif Timestamp attribute name + */ + private const TIMESTAMP = 'DateTimeOriginal'; + + /** + * Coordinate modulo + * Modulo between degree, minute, second + */ + private const COORDINATE_MODULO = 60; + + + /** + * Regex to extract date components from exif parameter + */ + private const EXIF_TIME_REGEX = '(?[0-9]{4})\:(?[0-9]{2})\:(?[0-9]{2}) (?[0-9]{2})\:(?[0-9]{2})\:(?[0-9]{2})'; + + /** + * @var int|null + */ + private $timestamp = null; + + /** + * @var float|null + */ + private $latitude = null; + + /** + * @var float|null + */ + private $longitude = null; + + /** + * @var bool|null + */ + private $is_valid = null; + + /** + * @var ?array + */ + protected $exif_data = null; + + /** + * @param string $path + * + * @return array|null + * @throws PelInvalidArgumentException + */ + protected static function get_exif_data_array(string $path) : array { + if (function_exists('exif_read_data')) { + $data = @exif_read_data($path, null, true); + if ($data && isset($data['EXIF']) && isset($data['EXIF'][self::LATITUDE]) && isset($data['EXIF'][self::LONGITUDE])) { + return $data['EXIF']; + } elseif ($data && isset($data['GPS']) && isset($data['GPS'][self::LATITUDE]) && isset($data['GPS'][self::LONGITUDE])) { $d = $data['GPS']; if (!isset($d[self::TIMESTAMP]) && isset($data['EXIF'][self::TIMESTAMP])) { $d[self::TIMESTAMP] = $data['EXIF'][self::TIMESTAMP]; } return $d; } - } - $data = new PelDataWindow(file_get_contents($path)); - if (PelJpeg::isValid($data)) { - $pelJpeg = new PelJpeg($data); - - $pelExif = $pelJpeg->getExif(); - if ($pelExif === null) { - return []; - } - - $pelTiff = $pelExif->getTiff(); - } elseif (PelTiff::isValid($data)) { - $pelTiff = new PelTiff($data); - } else { - return []; - } - if (is_null($pelTiff)) { - return []; - } - $pelIfd0 = $pelTiff->getIfd(); - if (is_null($pelIfd0)) { - return []; - } - $pelIfdExif = $pelIfd0->getSubIfd(PelIfd::EXIF); - - if (is_null($pelIfdExif)) { - return []; - } - $pelDateTimeOriginal = $pelIfdExif->getEntry(PelTag::DATE_TIME_ORIGINAL); - if (is_null($pelDateTimeOriginal)) { - return []; - } - $exif = [ - # self::TIMESTAMP => $pelDateTimeOriginal->getValue(PelEntryTime::EXIF_STRING) // for old pel 0.9.6 and above - self::TIMESTAMP => (int) $pelDateTimeOriginal->getValue() // for new pel >= 0.9.11 - ]; - $pelIfdGPS = $pelIfd0->getSubIfd(PelIfd::GPS); - if (!is_null($pelIfdGPS) && !is_null($pelIfdGPS->getEntry(PelTag::GPS_LATITUDE )) && !is_null( $pelIfdGPS->getEntry(PelTag::GPS_LONGITUDE))) { - static::readPelCoordinate($pelIfdGPS, - self::LATITUDE, PelTag::GPS_LATITUDE, - self::LATITUDE_REF, PelTag::GPS_LATITUDE_REF, - $exif - ); - static::readPelCoordinate($pelIfdGPS, - self::LONGITUDE, PelTag::GPS_LONGITUDE, - self::LONGITUDE_REF, PelTag::GPS_LONGITUDE_REF, - $exif - ); - } - Pel::clearExceptions(); - return $exif; - } - - /** - * @param PelIfd $pelIfdGPS - * @param $target - * @param $source - * @param $ref_target - * @param $ref_source - * @param array $exif - */ - protected static function readPelCoordinate( PelIfd $pelIfdGPS, $target, $source, $ref_target, $ref_source, array &$exif = [] ) : void{ - $coordinate = $pelIfdGPS->getEntry($source)->getValue(); - if ((int) $coordinate[0][1] !=0 && (int) $coordinate[1][1] !=0 && (int) $coordinate[2][1] !=0) { - $exif[$ref_target] = $pelIfdGPS->getEntry($ref_source)->getValue(); - $exif[$target] = [ - 0 => (int) $coordinate[0][0]/ (int) $coordinate[0][1], - 1 => (int) $coordinate[1][0]/ (int) $coordinate[1][1], - 2 => (int) $coordinate[2][0]/ (int) $coordinate[2][1] - ]; - } - } - - /** - * @param string $path - * @return ExifGeoData - */ - public static function get(string $path) : ?ExifGeoData{ - try{ + } + $data = new PelDataWindow(file_get_contents($path)); + if (PelJpeg::isValid($data)) { + $pelJpeg = new PelJpeg($data); + + $pelExif = $pelJpeg->getExif(); + if ($pelExif === null) { + return []; + } + + $pelTiff = $pelExif->getTiff(); + } elseif (PelTiff::isValid($data)) { + $pelTiff = new PelTiff($data); + } else { + return []; + } + if (is_null($pelTiff)) { + return []; + } + $pelIfd0 = $pelTiff->getIfd(); + if (is_null($pelIfd0)) { + return []; + } + $pelIfdExif = $pelIfd0->getSubIfd(PelIfd::EXIF); + + if (is_null($pelIfdExif)) { + return []; + } + $pelDateTimeOriginal = $pelIfdExif->getEntry(PelTag::DATE_TIME_ORIGINAL); + if (is_null($pelDateTimeOriginal)) { + return []; + } + $exif = [ + # self::TIMESTAMP => $pelDateTimeOriginal->getValue(PelEntryTime::EXIF_STRING) // for old pel 0.9.6 and above + self::TIMESTAMP => (int)$pelDateTimeOriginal->getValue() // for new pel >= 0.9.11 + ]; + $pelIfdGPS = $pelIfd0->getSubIfd(PelIfd::GPS); + if (!is_null($pelIfdGPS) && !is_null($pelIfdGPS->getEntry(PelTag::GPS_LATITUDE)) && !is_null($pelIfdGPS->getEntry(PelTag::GPS_LONGITUDE))) { + static::readPelCoordinate($pelIfdGPS, + self::LATITUDE, PelTag::GPS_LATITUDE, + self::LATITUDE_REF, PelTag::GPS_LATITUDE_REF, + $exif + ); + static::readPelCoordinate($pelIfdGPS, + self::LONGITUDE, PelTag::GPS_LONGITUDE, + self::LONGITUDE_REF, PelTag::GPS_LONGITUDE_REF, + $exif + ); + } + Pel::clearExceptions(); + return $exif; + } + + /** + * @param PelIfd $pelIfdGPS + * @param $target + * @param $source + * @param $ref_target + * @param $ref_source + * @param array $exif + */ + protected static function readPelCoordinate(PelIfd $pelIfdGPS, $target, $source, $ref_target, $ref_source, array &$exif = []) : void { + $coordinate = $pelIfdGPS->getEntry($source)->getValue(); + if ((int)$coordinate[0][1] != 0 && (int)$coordinate[1][1] != 0 && (int)$coordinate[2][1] != 0) { + $exif[$ref_target] = $pelIfdGPS->getEntry($ref_source)->getValue(); + $exif[$target] = [ + 0 => (int)$coordinate[0][0] / (int)$coordinate[0][1], + 1 => (int)$coordinate[1][0] / (int)$coordinate[1][1], + 2 => (int)$coordinate[2][0] / (int)$coordinate[2][1] + ]; + } + } + + /** + * @param string $path + * @return ExifGeoData + */ + public static function get(string $path) : ?ExifGeoData { + try { $data = static::get_exif_data_array($path); - }catch(\Throwable $e){ - $data = []; - } - return new static($data); - } - - /** - * ExifGeoData constructor. - * @param array $exif_data - */ - private final function __construct(array $exif_data) - { - $this->exif_data = $exif_data; - $this->parse(); - } + } catch (\Throwable $e) { + $data = []; + } + return new static($data); + } + + /** + * ExifGeoData constructor. + * @param array $exif_data + */ + final private function __construct(array $exif_data) { + $this->exif_data = $exif_data; + $this->parse(); + } /** * @param false $invalidate_zero_iland * @throws ExifDataInvalidException * @throws ExifDataNoLocationException */ - public function validate( $invalidate_zero_iland = false ) - { - if (!$this->exif_data) { - throw new ExifDataInvalidException('No exif_data found', 1); - } - if (!is_array($this->exif_data)) { - throw new ExifDataInvalidException('exif_data is not an array', 2); - } - - if (!isset($this->exif_data[self::LATITUDE]) || !isset($this->exif_data[self::LONGITUDE])) { - throw new ExifDataNoLocationException('Latitude and/or Longitude are missing from exif data', 1); - } - if( $invalidate_zero_iland && $this->isZeroIsland() ){ + public function validate($invalidate_zero_iland = false) { + if (!$this->exif_data) { + throw new ExifDataInvalidException('No exif_data found', 1); + } + if (!is_array($this->exif_data)) { + throw new ExifDataInvalidException('exif_data is not an array', 2); + } + + if (!isset($this->exif_data[self::LATITUDE]) || !isset($this->exif_data[self::LONGITUDE])) { + throw new ExifDataNoLocationException('Latitude and/or Longitude are missing from exif data', 1); + } + if ($invalidate_zero_iland && $this->isZeroIsland()) { $this->latitude = null; $this->longitude = null; - throw new ExifDataNoLocationException('Zero island is not valid', 2); - } - } - - /** - * @return bool - */ - public function isValid(): bool - { - if (null === $this->is_valid) { - try { - $this->validate(); - $this->is_valid = true; - } catch (\Throwable $e) { - $this->is_valid = false; - } - } - return $this->is_valid; - } - - /** - * @return bool - */ - private function parse() - { - if ($this->isValid() && (null === $this->latitude || null === $this->longitude)) { - $this->longitude = $this->geo2float($this->exif_data[self::LONGITUDE]); - if( isset($this->exif_data[self::LONGITUDE_REF]) && 'W' === $this->exif_data[self::LONGITUDE_REF] ){ - $this->longitude*=-1; - } - $this->latitude = $this->geo2float($this->exif_data[self::LATITUDE]); - if( isset($this->exif_data[self::LATITUDE_REF]) && 'S' === $this->exif_data[self::LATITUDE_REF] ){ - $this->latitude*=-1; - } - } + throw new ExifDataNoLocationException('Zero island is not valid', 2); + } + } + + /** + * @return bool + */ + public function isValid(): bool { + if ($this->is_valid === null) { + try { + $this->validate(); + $this->is_valid = true; + } catch (\Throwable $e) { + $this->is_valid = false; + } + } + return $this->is_valid; + } + + /** + * @return bool + */ + private function parse() { + if ($this->isValid() && ($this->latitude === null || $this->longitude === null)) { + $this->longitude = $this->geo2float($this->exif_data[self::LONGITUDE]); + if (isset($this->exif_data[self::LONGITUDE_REF]) && $this->exif_data[self::LONGITUDE_REF] === 'W') { + $this->longitude *= -1; + } + $this->latitude = $this->geo2float($this->exif_data[self::LATITUDE]); + if (isset($this->exif_data[self::LATITUDE_REF]) && $this->exif_data[self::LATITUDE_REF] === 'S') { + $this->latitude *= -1; + } + } // optional if (isset($this->exif_data[self::TIMESTAMP])) { $t = $this->exif_data[self::TIMESTAMP]; - $this->timestamp = is_string($t) ? $this->string2time($t) : ( is_int($t) ? $t : null ); + $this->timestamp = is_string($t) ? $this->string2time($t) : (is_int($t) ? $t : null); } - } - - /** - * @param string $timestamp - * @return int - */ - private function string2time(string $timestamp): ?int - { - $result = null; - if (preg_match('#' . self::EXIF_TIME_REGEX . '#ui', $timestamp, $match)) { - $result = - strtotime("{$match['years']}-{$match['months']}-{$match['days']} {$match['hours']}:{$match['minutes']}:{$match['seconds']}"); - } - return $result; - } - - - /** - * @param $geo - * @return float|null - */ - private function geo2float($geo): ?float - { - if (!is_array($geo)) { - $geo = [$geo]; - } - $result = .0; - $d = 1.0; - foreach ($geo as $component) { - $result += ($this->string2float($component) * $d); - $d /= self::COORDINATE_MODULO; - } - - return $result; - } - - /** - * @param string $value - * @return float|null - */ - private function string2float(string $value): ?float - { - $result = null; - $value = trim($value, '/'); - if (str_contains($value, '/')) { - $value = array_map('intval', explode('/', $value)); - if (0 != $value[1]) { - $result = $value[0] / $value[1]; - } - } else { - $result = floatval($value); - } - return $result; - - } - - /** - * @return bool - */ - public function isZeroIsland(): bool - { - return .0 === $this->latitude() && .0 === $this->longitude(); - } - - /** - * @return float - */ - public function latitude(int $precision = 6): ?float - { - return $this->latitude === null ? null : round($this->latitude,$precision); - } - - /** - * @return float - */ - public function longitude(int $precision = 6): ?float - { - return $this->longitude === null ? null : round($this->longitude,$precision); - } - - /** - * @param string|null $format - * @return string|int|null - */ - public function timestamp(?string $format = 'Y-m-d H:i:s') - { - $result = $this->timestamp; - if ($this->timestamp !== null && $format) { - $result = date($format, $this->timestamp); - } - return $result; - } - - /** - * If someone wants to have it as a json object - * - * @return array - */ - public function jsonSerialize() - { - return [ - 'lat'=>$this->lat, - 'lng'=>$this->lng, - 'dateTaken'=>$this->dateTaken - ]; - } - - /** - * Magic getter function - * - * @param $name - * @return float|int|string|null - */ - public function __get($name){ - $value = null; - switch($name){ - case 'lat': - $value = $this->latitude(); - break; - case 'lng': - $value = $this->longitude(); - break; - case 'dateTaken': - $value = $this->timestamp(null); - break; - } - return $value; - } + } + + /** + * @param string $timestamp + * @return int + */ + private function string2time(string $timestamp): ?int { + $result = null; + if (preg_match('#' . self::EXIF_TIME_REGEX . '#ui', $timestamp, $match)) { + $result = + strtotime("{$match['years']}-{$match['months']}-{$match['days']} {$match['hours']}:{$match['minutes']}:{$match['seconds']}"); + } + return $result; + } + + + /** + * @param $geo + * @return float|null + */ + private function geo2float($geo): ?float { + if (!is_array($geo)) { + $geo = [$geo]; + } + $result = .0; + $d = 1.0; + foreach ($geo as $component) { + $result += ($this->string2float($component) * $d); + $d /= self::COORDINATE_MODULO; + } + + return $result; + } + + /** + * @param string $value + * @return float|null + */ + private function string2float(string $value): ?float { + $result = null; + $value = trim($value, '/'); + if (str_contains($value, '/')) { + $value = array_map('intval', explode('/', $value)); + if ($value[1] != 0) { + $result = $value[0] / $value[1]; + } + } else { + $result = floatval($value); + } + return $result; + + } + + /** + * @return bool + */ + public function isZeroIsland(): bool { + return $this->latitude() === .0 && $this->longitude() === .0; + } + + /** + * @return float + */ + public function latitude(int $precision = 6): ?float { + return $this->latitude === null ? null : round($this->latitude, $precision); + } + + /** + * @return float + */ + public function longitude(int $precision = 6): ?float { + return $this->longitude === null ? null : round($this->longitude, $precision); + } + + /** + * @param string|null $format + * @return string|int|null + */ + public function timestamp(?string $format = 'Y-m-d H:i:s') { + $result = $this->timestamp; + if ($this->timestamp !== null && $format) { + $result = date($format, $this->timestamp); + } + return $result; + } + + /** + * If someone wants to have it as a json object + * + * @return array + */ + public function jsonSerialize() { + return [ + 'lat' => $this->lat, + 'lng' => $this->lng, + 'dateTaken' => $this->dateTaken + ]; + } + + /** + * Magic getter function + * + * @param $name + * @return float|int|string|null + */ + public function __get($name) { + $value = null; + switch ($name) { + case 'lat': + $value = $this->latitude(); + break; + case 'lng': + $value = $this->longitude(); + break; + case 'dateTaken': + $value = $this->timestamp(null); + break; + } + return $value; + } } diff --git a/lib/Helper/functions.php b/lib/Helper/functions.php index 1f825fc83..bfecf2f54 100644 --- a/lib/Helper/functions.php +++ b/lib/Helper/functions.php @@ -30,7 +30,7 @@ * @return string */ function remove_utf8_bom(string $text): string { - $bom = pack('H*','EFBBBF'); + $bom = pack('H*', 'EFBBBF'); $text = preg_replace("/^$bom/", '', $text); return $text; } diff --git a/lib/Hooks/FileHooks.php b/lib/Hooks/FileHooks.php index 7348664d3..1a09fe306 100644 --- a/lib/Hooks/FileHooks.php +++ b/lib/Hooks/FileHooks.php @@ -13,111 +13,108 @@ namespace OCA\Maps\Hooks; use OC\Files\Filesystem; -use OC\Files\View; +use OCA\Maps\Service\PhotofilesService; +use OCA\Maps\Service\TracksService; use OCP\Files\FileInfo; -use OCP\ILogger; -use OCP\Files\Node; use OCP\Files\IRootFolder; +use OCP\ILogger; use OCP\Lock\ILockingProvider; -use OCP\Util; -use OCP\Share; -use OCA\Maps\Service\PhotofilesService; -use OCA\Maps\Service\TracksService; +use OCP\Share; +use OCP\Util; /** * Handles files events */ class FileHooks { - private $photofilesService; - private $tracksService; + private $photofilesService; + private $tracksService; - private $logger; + private $logger; - private $root; + private $root; private ILockingProvider $lockingProvider; public function __construct(IRootFolder $root, PhotofilesService $photofilesService, TracksService $tracksService, - ILogger $logger, $appName, ILockingProvider $lockingProvider) { - $this->photofilesService = $photofilesService; - $this->tracksService = $tracksService; - $this->logger = $logger; - $this->root = $root; - $this->lockingProvider = $lockingProvider; - } - - public function register() { - $fileWriteCallback = function(\OCP\Files\Node $node) { - if ($this->isUserNode($node) && $node->getSize() > 0) { - $path = $node->getPath(); - if (!$this->lockingProvider->isLocked($path, ILockingProvider::LOCK_SHARED) - and !$this->lockingProvider->isLocked($path, ILockingProvider::LOCK_EXCLUSIVE) - ) { - $isPhoto = $this->photofilesService->addByFile($node); - if (!$isPhoto) { - $this->tracksService->safeAddByFile($node); - } - } - } - }; - $this->root->listen('\OC\Files', 'postWrite', $fileWriteCallback); - - $fileDeletionCallback = function(\OCP\Files\Node $node) { - if ($this->isUserNode($node)) { - if ($node->getType() === FileInfo::TYPE_FOLDER) { - $this->photofilesService->deleteByFolder($node); - $this->tracksService->deleteByFolder($node); - } else { - $this->photofilesService->deleteByFile($node); - $this->tracksService->deleteByFile($node); - } - } - }; - $this->root->listen('\OC\Files', 'preDelete', $fileDeletionCallback); - - // this one is triggered when restoring a version of a file - // and NOT when it's created so we can use it for updating coordinates in DB - $this->root->listen('\OC\Files', 'postTouch', function(\OCP\Files\Node $node) { - if ($this->isUserNode($node) and $node->getType() === FileInfo::TYPE_FILE) { - $this->photofilesService->updateByFile($node); - // nothing to update on tracks, metadata will be regenerated when getting content if etag has changed - } - }); - - // move file: delete then add it again in DB to be sure it's there for all users with access to target file - $this->root->listen('\OC\Files', 'postRename', function(\OCP\Files\Node $source, \OCP\Files\Node $target) { - if ($this->isUserNode($target)) { - if ($target->getType() === FileInfo::TYPE_FILE) { - // if moved (parents are different) => update DB with access list - if ($source->getParent()->getId() !== $target->getParent()->getId()) { + ILogger $logger, $appName, ILockingProvider $lockingProvider) { + $this->photofilesService = $photofilesService; + $this->tracksService = $tracksService; + $this->logger = $logger; + $this->root = $root; + $this->lockingProvider = $lockingProvider; + } + + public function register() { + $fileWriteCallback = function (\OCP\Files\Node $node) { + if ($this->isUserNode($node) && $node->getSize() > 0) { + $path = $node->getPath(); + if (!$this->lockingProvider->isLocked($path, ILockingProvider::LOCK_SHARED) + and !$this->lockingProvider->isLocked($path, ILockingProvider::LOCK_EXCLUSIVE) + ) { + $isPhoto = $this->photofilesService->addByFile($node); + if (!$isPhoto) { + $this->tracksService->safeAddByFile($node); + } + } + } + }; + $this->root->listen('\OC\Files', 'postWrite', $fileWriteCallback); + + $fileDeletionCallback = function (\OCP\Files\Node $node) { + if ($this->isUserNode($node)) { + if ($node->getType() === FileInfo::TYPE_FOLDER) { + $this->photofilesService->deleteByFolder($node); + $this->tracksService->deleteByFolder($node); + } else { + $this->photofilesService->deleteByFile($node); + $this->tracksService->deleteByFile($node); + } + } + }; + $this->root->listen('\OC\Files', 'preDelete', $fileDeletionCallback); + + // this one is triggered when restoring a version of a file + // and NOT when it's created so we can use it for updating coordinates in DB + $this->root->listen('\OC\Files', 'postTouch', function (\OCP\Files\Node $node) { + if ($this->isUserNode($node) and $node->getType() === FileInfo::TYPE_FILE) { + $this->photofilesService->updateByFile($node); + // nothing to update on tracks, metadata will be regenerated when getting content if etag has changed + } + }); + + // move file: delete then add it again in DB to be sure it's there for all users with access to target file + $this->root->listen('\OC\Files', 'postRename', function (\OCP\Files\Node $source, \OCP\Files\Node $target) { + if ($this->isUserNode($target)) { + if ($target->getType() === FileInfo::TYPE_FILE) { + // if moved (parents are different) => update DB with access list + if ($source->getParent()->getId() !== $target->getParent()->getId()) { // we renamed therefore target and source are identical - $this->photofilesService->deleteByFile($target); - $this->photofilesService->addByFile($target); - // tracks: nothing to do here because we use fileID - } - } - elseif ($target->getType() === FileInfo::TYPE_FOLDER) { - if ($source->getParent()->getId() !== $target->getParent()->getId()) { + $this->photofilesService->deleteByFile($target); + $this->photofilesService->addByFile($target); + // tracks: nothing to do here because we use fileID + } + } elseif ($target->getType() === FileInfo::TYPE_FOLDER) { + if ($source->getParent()->getId() !== $target->getParent()->getId()) { // we renamed therefore target and source have the same childs. - $this->photofilesService->deleteByFolder($target); - $this->photofilesService->addByFolder($target); - // tracks: nothing to do here because we use fileID - } - } - } - }); - - Util::connectHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', $this, 'restore'); - - // sharing hooks - Util::connectHook(\OCP\Share::class, 'post_shared', $this, 'postShare'); - Util::connectHook(\OCP\Share::class, 'post_unshare', $this, 'postUnShare'); - Util::connectHook(\OCP\Share::class, 'pre_unshare', $this, 'preUnShare'); - } - - public function postShare($params) { + $this->photofilesService->deleteByFolder($target); + $this->photofilesService->addByFolder($target); + // tracks: nothing to do here because we use fileID + } + } + } + }); + + Util::connectHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', $this, 'restore'); + + // sharing hooks + Util::connectHook(\OCP\Share::class, 'post_shared', $this, 'postShare'); + Util::connectHook(\OCP\Share::class, 'post_unshare', $this, 'postUnShare'); + Util::connectHook(\OCP\Share::class, 'pre_unshare', $this, 'preUnShare'); + } + + public function postShare($params) { if ($params['itemType'] === 'file') { //$targetFilePath = $params['itemTarget']; //$sourceUserId = $params['uidOwner']; @@ -127,10 +124,9 @@ public function postShare($params) { return; } $file = array_shift($files); - $this->photofilesService->addByFile($file,); + $this->photofilesService->addByFile($file, ); $this->tracksService->safeAddByFile($file); - } - else if ($params['itemType'] === 'folder') { + } elseif ($params['itemType'] === 'folder') { $dirId = $params['fileSource']; // or itemSource $folders = $this->root->getById($dirId); if (empty($folders)) { @@ -140,55 +136,55 @@ public function postShare($params) { $this->photofilesService->addByFolder($folder); $this->tracksService->safeAddByFolder($folder); } - } - - public function postUnShare($params) { - if ($params['shareType'] === Share::SHARE_TYPE_USER) { - if ($params['itemType'] === 'file') { - $targetUserId = $params['shareWith']; - $fileId = $params['fileSource']; // or itemSource - $this->photofilesService->deleteByFileIdUserId($fileId, $targetUserId); - $this->tracksService->safeDeleteByFileIdUserId($fileId, $targetUserId); - } - } - } - - public function preUnShare($params) { - if ($params['shareType'] === Share::SHARE_TYPE_USER) { - if ($params['itemType'] === 'folder') { - $targetUserId = $params['shareWith']; - $dirId = $params['fileSource']; // or itemSource - $this->photofilesService->deleteByFolderIdUserId($dirId, $targetUserId); - $this->tracksService->safeDeleteByFolderIdUserId($dirId, $targetUserId); - } - } - } - - public function restore($params) { - $node = $this->getNodeForPath($params['filePath']); - if ($this->isUserNode($node)) { - if ($node->getType() === FileInfo::TYPE_FOLDER) { - $this->photofilesService->addByFolder($node); - $this->tracksService->safeAddByFolder($node); - } else { - $this->photofilesService->addByFile($node); - $this->tracksService->safeAddByFile($node); - } - } - } - - private function getNodeForPath($path) { - $user = \OC::$server->getUserSession()->getUser(); - $fullPath = Filesystem::normalizePath('/' . $user->getUID() . '/files/' . $path); - return $this->root->get($fullPath); - } - - /** - * Ugly Hack, find API way to check if file is added by user. - */ - private function isUserNode(\OCP\Files\Node $node) { - //return strpos($node->getStorage()->getId(), "home::", 0) === 0; - return $node->getStorage()->instanceOfStorage('\OC\Files\Storage\Home'); - } + } + + public function postUnShare($params) { + if ($params['shareType'] === Share::SHARE_TYPE_USER) { + if ($params['itemType'] === 'file') { + $targetUserId = $params['shareWith']; + $fileId = $params['fileSource']; // or itemSource + $this->photofilesService->deleteByFileIdUserId($fileId, $targetUserId); + $this->tracksService->safeDeleteByFileIdUserId($fileId, $targetUserId); + } + } + } + + public function preUnShare($params) { + if ($params['shareType'] === Share::SHARE_TYPE_USER) { + if ($params['itemType'] === 'folder') { + $targetUserId = $params['shareWith']; + $dirId = $params['fileSource']; // or itemSource + $this->photofilesService->deleteByFolderIdUserId($dirId, $targetUserId); + $this->tracksService->safeDeleteByFolderIdUserId($dirId, $targetUserId); + } + } + } + + public function restore($params) { + $node = $this->getNodeForPath($params['filePath']); + if ($this->isUserNode($node)) { + if ($node->getType() === FileInfo::TYPE_FOLDER) { + $this->photofilesService->addByFolder($node); + $this->tracksService->safeAddByFolder($node); + } else { + $this->photofilesService->addByFile($node); + $this->tracksService->safeAddByFile($node); + } + } + } + + private function getNodeForPath($path) { + $user = \OC::$server->getUserSession()->getUser(); + $fullPath = Filesystem::normalizePath('/' . $user->getUID() . '/files/' . $path); + return $this->root->get($fullPath); + } + + /** + * Ugly Hack, find API way to check if file is added by user. + */ + private function isUserNode(\OCP\Files\Node $node) { + //return strpos($node->getStorage()->getId(), "home::", 0) === 0; + return $node->getStorage()->instanceOfStorage('\OC\Files\Storage\Home'); + } } diff --git a/lib/Listener/CardCreatedListener.php b/lib/Listener/CardCreatedListener.php index 24f2d7906..592d925c1 100644 --- a/lib/Listener/CardCreatedListener.php +++ b/lib/Listener/CardCreatedListener.php @@ -23,11 +23,11 @@ namespace OCA\Maps\Listener; -use OCP\ILogger; use OCA\DAV\Events\CardCreatedEvent; use OCA\Maps\Service\AddressService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; +use OCP\ILogger; class CardCreatedListener implements IEventListener { @@ -50,7 +50,7 @@ public function handle(Event $event): void { return; } $cData = $event->getCardData(); - $cUri = $cData["uri"]; - $this->addressService->scheduleVCardForLookup($cData["carddata"], $cUri); + $cUri = $cData['uri']; + $this->addressService->scheduleVCardForLookup($cData['carddata'], $cUri); } } diff --git a/lib/Listener/CardDeletedListener.php b/lib/Listener/CardDeletedListener.php index 277d3532f..91e67185e 100644 --- a/lib/Listener/CardDeletedListener.php +++ b/lib/Listener/CardDeletedListener.php @@ -23,11 +23,11 @@ namespace OCA\Maps\Listener; -use OCP\ILogger; use OCA\DAV\Events\CardDeletedEvent; use OCA\Maps\Service\AddressService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; +use OCP\ILogger; class CardDeletedListener implements IEventListener { @@ -50,7 +50,7 @@ public function handle(Event $event): void { return; } $cData = $event->getCardData(); - $cUri = $cData["uri"]; + $cUri = $cData['uri']; $this->addressService->deleteDBContactAddresses($cUri); } } diff --git a/lib/Listener/CardUpdatedListener.php b/lib/Listener/CardUpdatedListener.php index 492b1fb13..4729f5537 100644 --- a/lib/Listener/CardUpdatedListener.php +++ b/lib/Listener/CardUpdatedListener.php @@ -23,11 +23,11 @@ namespace OCA\Maps\Listener; -use OCP\ILogger; use OCA\DAV\Events\CardUpdatedEvent; use OCA\Maps\Service\AddressService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; +use OCP\ILogger; class CardUpdatedListener implements IEventListener { @@ -50,7 +50,7 @@ public function handle(Event $event): void { return; } $cData = $event->getCardData(); - $cUri = $cData["uri"]; - $this->addressService->scheduleVCardForLookup($cData["carddata"], $cUri); + $cUri = $cData['uri']; + $this->addressService->scheduleVCardForLookup($cData['carddata'], $cUri); } } diff --git a/lib/Listener/LoadAdditionalScriptsListener.php b/lib/Listener/LoadAdditionalScriptsListener.php index e0f42f33d..8b68bb868 100644 --- a/lib/Listener/LoadAdditionalScriptsListener.php +++ b/lib/Listener/LoadAdditionalScriptsListener.php @@ -23,7 +23,6 @@ namespace OCA\Maps\Listener; -use OCP\ILogger; use OCA\Files\Event\LoadAdditionalScriptsEvent; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; diff --git a/lib/Migration/InstallScan.php b/lib/Migration/InstallScan.php index 2a05efc4e..079221d72 100644 --- a/lib/Migration/InstallScan.php +++ b/lib/Migration/InstallScan.php @@ -23,19 +23,17 @@ namespace OCA\Maps\Migration; +use OCA\Maps\BackgroundJob\LaunchUsersInstallScanJob; +use OCP\BackgroundJob\IJobList; use OCP\Encryption\IManager; -use OCP\Files\NotFoundException; -use OCP\IUser; -use OCP\IUserManager; -use \OCP\BackgroundJob\IJobList; - use OCP\IConfig; + use OCP\IDBConnection; +use OCP\IUser; +use OCP\IUserManager; use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; -use OCP\Share; -use \OCA\Maps\BackgroundJob\LaunchUsersInstallScanJob; +use OCP\Migration\IRepairStep; /** * Class InstallScan @@ -47,16 +45,16 @@ class InstallScan implements IRepairStep { /** @var IDBConnection */ private $connection; - /** @var IConfig */ + /** @var IConfig */ private $config; public function __construct(IDBConnection $connection, - IConfig $config, - IUserManager $userManager, - IJobList $jobList, - IManager $encryptionManager - ) { + IConfig $config, + IUserManager $userManager, + IJobList $jobList, + IManager $encryptionManager + ) { $this->connection = $connection; $this->config = $config; $this->jobList = $jobList; diff --git a/lib/Migration/RegisterMimeType.php b/lib/Migration/RegisterMimeType.php index 996f34f73..735bdf2d0 100644 --- a/lib/Migration/RegisterMimeType.php +++ b/lib/Migration/RegisterMimeType.php @@ -6,24 +6,20 @@ use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; -class RegisterMimeType implements IRepairStep -{ - const CUSTOM_MIMETYPEMAPPING = 'mimetypemapping.json'; +class RegisterMimeType implements IRepairStep { + public const CUSTOM_MIMETYPEMAPPING = 'mimetypemapping.json'; protected IMimeTypeLoader $mimeTypeLoader; - public function __construct(IMimeTypeLoader $mimeTypeLoader) - { + public function __construct(IMimeTypeLoader $mimeTypeLoader) { $this->mimeTypeLoader = $mimeTypeLoader; } - public function getName() - { + public function getName() { return 'Register Maps MIME types"'; } - private function registerForExistingFiles() - { + private function registerForExistingFiles() { $mimeTypeId = $this->mimeTypeLoader->getId('application/x-nextcloud-maps'); $this->mimeTypeLoader->updateFilecache('maps', $mimeTypeId); @@ -40,15 +36,14 @@ private function registerForExistingFiles() $this->mimeTypeLoader->updateFilecache('notrack', $mimeTypeId); } - private function registerForNewFiles() - { + private function registerForNewFiles() { $mapping = [ 'maps' => ['application/x-nextcloud-maps'], 'noindex' => ['application/x-nextcloud-noindex'], 'nomedia' => ['application/x-nextcloud-nomedia'], 'noimage' => ['application/x-nextcloud-noimage'], 'notrack' => ['application/x-nextcloud-maps-notrack'], - ]; + ]; $mappingFile = \OC::$configDir . self::CUSTOM_MIMETYPEMAPPING; if (file_exists($mappingFile)) { @@ -61,8 +56,7 @@ private function registerForNewFiles() file_put_contents($mappingFile, json_encode($mapping, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); } - public function run(IOutput $output) - { + public function run(IOutput $output) { $output->info('Registering the mimetype...'); // Register the mime type for existing files diff --git a/lib/Migration/UnregisterMimeType.php b/lib/Migration/UnregisterMimeType.php index 89997e0f3..d302d9a2f 100644 --- a/lib/Migration/UnregisterMimeType.php +++ b/lib/Migration/UnregisterMimeType.php @@ -6,24 +6,20 @@ use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; -class UnregisterMimeType implements IRepairStep -{ - const CUSTOM_MIMETYPEMAPPING = 'mimetypemapping.json'; +class UnregisterMimeType implements IRepairStep { + public const CUSTOM_MIMETYPEMAPPING = 'mimetypemapping.json'; protected IMimeTypeLoader $mimeTypeLoader; - public function __construct(IMimeTypeLoader $mimeTypeLoader) - { + public function __construct(IMimeTypeLoader $mimeTypeLoader) { $this->mimeTypeLoader = $mimeTypeLoader; } - public function getName() - { + public function getName() { return 'Register Maps MIME types"'; } - private function unregisterForExistingFiles() - { + private function unregisterForExistingFiles() { $mimeTypeId = $this->mimeTypeLoader->getId('application/octet-stream'); $this->mimeTypeLoader->updateFilecache('maps', $mimeTypeId); $this->mimeTypeLoader->updateFilecache('noindex', $mimeTypeId); @@ -32,8 +28,7 @@ private function unregisterForExistingFiles() $this->mimeTypeLoader->updateFilecache('notrack', $mimeTypeId); } - private function unregisterForNewFiles() - { + private function unregisterForNewFiles() { $mappingFile = \OC::$configDir . self::CUSTOM_MIMETYPEMAPPING; if (file_exists($mappingFile)) { @@ -51,8 +46,7 @@ private function unregisterForNewFiles() } } - public function run(IOutput $output) - { + public function run(IOutput $output) { $output->info('Unregistering the mimetype...'); // Register the mime type for existing files @@ -64,4 +58,3 @@ public function run(IOutput $output) $output->info('The mimetype was successfully unregistered.'); } } - diff --git a/lib/Migration/Version000008Date20190428142257.php b/lib/Migration/Version000008Date20190428142257.php index f9e96c6fc..69676057a 100644 --- a/lib/Migration/Version000008Date20190428142257.php +++ b/lib/Migration/Version000008Date20190428142257.php @@ -6,8 +6,8 @@ use Closure; use OCP\DB\ISchemaWrapper; -use OCP\Migration\SimpleMigrationStep; use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; /** * Auto-generated migration step: Please modify to your needs! diff --git a/lib/Migration/Version000009Date20190625000800.php b/lib/Migration/Version000009Date20190625000800.php index b148d05b6..a426e698f 100644 --- a/lib/Migration/Version000009Date20190625000800.php +++ b/lib/Migration/Version000009Date20190625000800.php @@ -6,8 +6,8 @@ use Closure; use OCP\DB\ISchemaWrapper; -use OCP\Migration\SimpleMigrationStep; use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; /** * Auto-generated migration step: Please modify to your needs! diff --git a/lib/Migration/Version000012Date20190703155323.php b/lib/Migration/Version000012Date20190703155323.php index 5f2b6dfca..430d1899b 100644 --- a/lib/Migration/Version000012Date20190703155323.php +++ b/lib/Migration/Version000012Date20190703155323.php @@ -6,10 +6,9 @@ use Closure; use OCP\DB\ISchemaWrapper; -use OCP\Migration\SimpleMigrationStep; -use OCP\Migration\IOutput; use OCP\IDBConnection; -use Doctrine\DBAL\Types\Type; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; /** * Auto-generated migration step: Please modify to your needs! diff --git a/lib/Migration/Version000012Date20190722184716.php b/lib/Migration/Version000012Date20190722184716.php index ce8701373..2f3e0af28 100644 --- a/lib/Migration/Version000012Date20190722184716.php +++ b/lib/Migration/Version000012Date20190722184716.php @@ -6,10 +6,9 @@ use Closure; use OCP\DB\ISchemaWrapper; -use OCP\Migration\SimpleMigrationStep; -use OCP\Migration\IOutput; use OCP\IDBConnection; -use Doctrine\DBAL\Types\Type; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; /** * Auto-generated migration step: Please modify to your needs! diff --git a/lib/Migration/Version000013Date20190723185417.php b/lib/Migration/Version000013Date20190723185417.php index c557ebdd6..f4642f34a 100644 --- a/lib/Migration/Version000013Date20190723185417.php +++ b/lib/Migration/Version000013Date20190723185417.php @@ -6,10 +6,9 @@ use Closure; use OCP\DB\ISchemaWrapper; -use OCP\Migration\SimpleMigrationStep; -use OCP\Migration\IOutput; use OCP\IDBConnection; -use Doctrine\DBAL\Types\Type; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; /** * Auto-generated migration step: Please modify to your needs! diff --git a/lib/Migration/Version000014Date20190817184844.php b/lib/Migration/Version000014Date20190817184844.php index 4d35b5f86..c84713d67 100644 --- a/lib/Migration/Version000014Date20190817184844.php +++ b/lib/Migration/Version000014Date20190817184844.php @@ -6,10 +6,9 @@ use Closure; use OCP\DB\ISchemaWrapper; -use OCP\Migration\SimpleMigrationStep; -use OCP\Migration\IOutput; use OCP\IDBConnection; -use Doctrine\DBAL\Types\Type; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; /** * Auto-generated migration step: Please modify to your needs! diff --git a/lib/Migration/Version000102Date20190901152326.php b/lib/Migration/Version000102Date20190901152326.php index cf75ac9b1..043abb257 100644 --- a/lib/Migration/Version000102Date20190901152326.php +++ b/lib/Migration/Version000102Date20190901152326.php @@ -6,10 +6,9 @@ use Closure; use OCP\DB\ISchemaWrapper; -use OCP\Migration\SimpleMigrationStep; -use OCP\Migration\IOutput; use OCP\IDBConnection; -use Doctrine\DBAL\Types\Type; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; /** * Auto-generated migration step: Please modify to your needs! diff --git a/lib/Migration/Version000106Date20191118221134.php b/lib/Migration/Version000106Date20191118221134.php index 386ba98e4..929531421 100644 --- a/lib/Migration/Version000106Date20191118221134.php +++ b/lib/Migration/Version000106Date20191118221134.php @@ -14,55 +14,55 @@ */ class Version000106Date20191118221134 extends SimpleMigrationStep { - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - */ - public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { - } + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + */ + public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { + } - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * @return null|ISchemaWrapper - */ - public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) { - /** @var ISchemaWrapper $schema */ - $schema = $schemaClosure(); + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); - if (!$schema->hasTable('maps_favorite_shares')) { - $table = $schema->createTable('maps_favorite_shares'); - $table->addColumn('id', 'bigint', [ - 'autoincrement' => true, - 'notnull' => true, - 'length' => 41, - ]); - $table->addColumn('owner', 'string', [ - 'notnull' => true, - 'length' => 64, - ]); - $table->addColumn('category', 'string', [ - 'notnull' => true, - 'length' => 64, - ]); - $table->addColumn('token', 'string', [ - 'notnull' => true, - 'length' => 64, - ]); + if (!$schema->hasTable('maps_favorite_shares')) { + $table = $schema->createTable('maps_favorite_shares'); + $table->addColumn('id', 'bigint', [ + 'autoincrement' => true, + 'notnull' => true, + 'length' => 41, + ]); + $table->addColumn('owner', 'string', [ + 'notnull' => true, + 'length' => 64, + ]); + $table->addColumn('category', 'string', [ + 'notnull' => true, + 'length' => 64, + ]); + $table->addColumn('token', 'string', [ + 'notnull' => true, + 'length' => 64, + ]); - $table->setPrimaryKey(['id']); - } + $table->setPrimaryKey(['id']); + } - return $schema; - } + return $schema; + } - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - */ - public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { - } + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + */ + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { + } } diff --git a/lib/Migration/Version000107Date20200608220000.php b/lib/Migration/Version000107Date20200608220000.php index 50aff027e..2e418f998 100644 --- a/lib/Migration/Version000107Date20200608220000.php +++ b/lib/Migration/Version000107Date20200608220000.php @@ -6,10 +6,9 @@ use Closure; use OCP\DB\ISchemaWrapper; -use OCP\Migration\SimpleMigrationStep; -use OCP\Migration\IOutput; use OCP\IDBConnection; -use Doctrine\DBAL\Types\Type; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; /** * Auto-generated migration step: Please modify to your needs! diff --git a/lib/Migration/Version000108Date20230310220000.php b/lib/Migration/Version000108Date20230310220000.php index faec68878..c8f323548 100644 --- a/lib/Migration/Version000108Date20230310220000.php +++ b/lib/Migration/Version000108Date20230310220000.php @@ -6,10 +6,9 @@ use Closure; use OCP\DB\ISchemaWrapper; -use OCP\Migration\SimpleMigrationStep; -use OCP\Migration\IOutput; use OCP\IDBConnection; -use Doctrine\DBAL\Types\Type; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; /** * Auto-generated migration step: Please modify to your needs! diff --git a/lib/Migration/Version100100Date20230731135102.php b/lib/Migration/Version100100Date20230731135102.php index 8327bc871..85a15fd68 100644 --- a/lib/Migration/Version100100Date20230731135102.php +++ b/lib/Migration/Version100100Date20230731135102.php @@ -6,10 +6,9 @@ use Closure; use OCP\DB\ISchemaWrapper; -use OCP\Migration\SimpleMigrationStep; -use OCP\Migration\IOutput; use OCP\IDBConnection; -use Doctrine\DBAL\Types\Type; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; /** * Auto-generated migration step: Please modify to your needs! diff --git a/lib/Service/AddressService.php b/lib/Service/AddressService.php index 720d1c9bc..3ba520922 100644 --- a/lib/Service/AddressService.php +++ b/lib/Service/AddressService.php @@ -12,16 +12,16 @@ namespace OCA\Maps\Service; -use \OCA\Maps\BackgroundJob\LookupMissingGeoJob; +use OCA\Maps\BackgroundJob\LookupMissingGeoJob; +use OCP\BackgroundJob\IJobList; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\Files\IAppData; use OCP\ICacheFactory; -use \OCP\ILogger; -use \OCP\IDBConnection; -use \OCP\BackgroundJob\IJobList; -use \OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IDBConnection; +use OCP\ILogger; use OCP\IMemcache; -use \Sabre\VObject\Reader; -use \OCP\Files\IAppData; use OpenLocationCode\OpenLocationCode; +use Sabre\VObject\Reader; /** * Class AddressService @@ -39,303 +39,301 @@ * @package OCA\Maps\Service */ class AddressService { - private $qb; - private $dbconnection; - private $logger; - private $jobList; - private $appData; + private $qb; + private $dbconnection; + private $logger; + private $jobList; + private $appData; /** @var IMemcache */ private $memcache; - public function __construct(ICacheFactory $cacheFactory, ILogger $logger, IJobList $jobList, - IAppData $appData, IDBConnection $dbconnection) { - $this->dbconnection = $dbconnection; - $this->qb = $dbconnection->getQueryBuilder(); - $this->memcache = $cacheFactory->createLocal('maps'); - $this->logger = $logger; - $this->jobList = $jobList; - $this->appData = $appData; - } + public function __construct(ICacheFactory $cacheFactory, ILogger $logger, IJobList $jobList, + IAppData $appData, IDBConnection $dbconnection) { + $this->dbconnection = $dbconnection; + $this->qb = $dbconnection->getQueryBuilder(); + $this->memcache = $cacheFactory->createLocal('maps'); + $this->logger = $logger; + $this->jobList = $jobList; + $this->appData = $appData; + } - // converts the address to geo lat;lon - public function addressToGeo($adr, $uri): string { - $geo = $this->lookupAddress($adr, $uri); - return strval($geo[0]).';'.strval($geo[1]); - } + // converts the address to geo lat;lon + public function addressToGeo($adr, $uri): string { + $geo = $this->lookupAddress($adr, $uri); + return strval($geo[0]).';'.strval($geo[1]); + } - /** - * Safely looks up an adr string - * First: Checks if the adress is known and in the db - * Uses this geo if it was looked up externally - * Look's it up if it was not looked up - * @param $adr - * @param $uri ressource identifier (contact URI for example) - * @return array($lat,$lng,$lookedUp) - */ - public function lookupAddress($adr, $uri): array { - $adr_norm = strtolower(preg_replace('/\s+/', '', $adr)); - $this->qb->select('id', 'lat', 'lng', 'looked_up') - ->from('maps_address_geo') - ->where($this->qb->expr()->eq('object_uri', $this->qb->createNamedParameter($uri, IQueryBuilder::PARAM_STR))) - ->andWhere($this->qb->expr()->eq('adr_norm', $this->qb->createNamedParameter($adr_norm, IQueryBuilder::PARAM_STR))); - $req = $this->qb->execute(); - $lat = null; - $lng = null; - $inDb = false; - while ($row = $req->fetch()) { - if ($row['looked_up']) { - $id = $row['id']; - $lat = $row['lat']; - $lng = $row['lng']; - $lookedUp = false; - $inDb = true; - } - else { - $id = $row['id']; - // if it's in the DB but not yet looked up, we can do it now - // we first check if this address was already looked up - $geo = $this->lookupAddressInternal($adr); - // if not, ask external service - if (!$geo[2]) { - $geo = $this->lookupAddressExternal($adr); - } - $lat = $geo[0]; - $lng = $geo[1]; - $lookedUp = $geo[2]; - $inDb = true; - } - break; - } - $req->closeCursor(); - $qb = $this->qb->resetQueryParts(); - // if it's still not in the DB, it means the lookup did not happen yet - // so we can schedule it for later - if (!$inDb) { - $foo = $this->scheduleForLookup($adr, $uri); - $id = $foo[0]; - $lat = $foo[1]; - $lng = $foo[2]; - $lookedUp = $foo[3]; + /** + * Safely looks up an adr string + * First: Checks if the adress is known and in the db + * Uses this geo if it was looked up externally + * Look's it up if it was not looked up + * @param $adr + * @param $uri ressource identifier (contact URI for example) + * @return array($lat,$lng,$lookedUp) + */ + public function lookupAddress($adr, $uri): array { + $adr_norm = strtolower(preg_replace('/\s+/', '', $adr)); + $this->qb->select('id', 'lat', 'lng', 'looked_up') + ->from('maps_address_geo') + ->where($this->qb->expr()->eq('object_uri', $this->qb->createNamedParameter($uri, IQueryBuilder::PARAM_STR))) + ->andWhere($this->qb->expr()->eq('adr_norm', $this->qb->createNamedParameter($adr_norm, IQueryBuilder::PARAM_STR))); + $req = $this->qb->execute(); + $lat = null; + $lng = null; + $inDb = false; + while ($row = $req->fetch()) { + if ($row['looked_up']) { + $id = $row['id']; + $lat = $row['lat']; + $lng = $row['lng']; + $lookedUp = false; + $inDb = true; + } else { + $id = $row['id']; + // if it's in the DB but not yet looked up, we can do it now + // we first check if this address was already looked up + $geo = $this->lookupAddressInternal($adr); + // if not, ask external service + if (!$geo[2]) { + $geo = $this->lookupAddressExternal($adr); + } + $lat = $geo[0]; + $lng = $geo[1]; + $lookedUp = $geo[2]; + $inDb = true; + } + break; + } + $req->closeCursor(); + $qb = $this->qb->resetQueryParts(); + // if it's still not in the DB, it means the lookup did not happen yet + // so we can schedule it for later + if (!$inDb) { + $foo = $this->scheduleForLookup($adr, $uri); + $id = $foo[0]; + $lat = $foo[1]; + $lng = $foo[2]; + $lookedUp = $foo[3]; - } - else { - if ($lookedUp) { - $this->qb->update('maps_address_geo') - ->set('lat', $qb->createNamedParameter($lat, IQueryBuilder::PARAM_STR)) - ->set('lng', $qb->createNamedParameter($lng, IQueryBuilder::PARAM_STR)) - ->set('object_uri', $qb->createNamedParameter($uri, IQueryBuilder::PARAM_STR)) - ->set('looked_up', $qb->createNamedParameter($lookedUp, IQueryBuilder::PARAM_BOOL)) - ->where($this->qb->expr()->eq('id', $this->qb->createNamedParameter($id, IQueryBuilder::PARAM_STR))); - $req = $this->qb->execute(); - $qb = $this->qb->resetQueryParts(); - } - } + } else { + if ($lookedUp) { + $this->qb->update('maps_address_geo') + ->set('lat', $qb->createNamedParameter($lat, IQueryBuilder::PARAM_STR)) + ->set('lng', $qb->createNamedParameter($lng, IQueryBuilder::PARAM_STR)) + ->set('object_uri', $qb->createNamedParameter($uri, IQueryBuilder::PARAM_STR)) + ->set('looked_up', $qb->createNamedParameter($lookedUp, IQueryBuilder::PARAM_BOOL)) + ->where($this->qb->expr()->eq('id', $this->qb->createNamedParameter($id, IQueryBuilder::PARAM_STR))); + $req = $this->qb->execute(); + $qb = $this->qb->resetQueryParts(); + } + } - return [$lat, $lng, $lookedUp]; - } + return [$lat, $lng, $lookedUp]; + } - private function lookupAddressInternal($adr): array { - $res = [null, null, False]; + private function lookupAddressInternal($adr): array { + $res = [null, null, false]; - if (OpenLocationCode::isFull($adr)) { - $decoded = OpenLocationCode::decode($adr); - $res[0] = $decoded['latitudeCenter']; - $res[1] = $decoded['longitudeCenter']; - $res[2] = True; - return $res; - } + if (OpenLocationCode::isFull($adr)) { + $decoded = OpenLocationCode::decode($adr); + $res[0] = $decoded['latitudeCenter']; + $res[1] = $decoded['longitudeCenter']; + $res[2] = true; + return $res; + } - $adr_norm = strtolower(preg_replace('/\s+/', '', $adr)); + $adr_norm = strtolower(preg_replace('/\s+/', '', $adr)); - $this->qb->select('lat', 'lng') - ->from('maps_address_geo') - ->where($this->qb->expr()->eq('looked_up', $this->qb->createNamedParameter(True, IQueryBuilder::PARAM_BOOL))) - ->andWhere($this->qb->expr()->eq('adr_norm', $this->qb->createNamedParameter($adr_norm, IQueryBuilder::PARAM_STR))); - $req = $this->qb->execute(); - while ($row = $req->fetch()) { - $res[0] = $row['lat']; - $res[1] = $row['lng']; - $res[2] = True; - } - $req->closeCursor(); - $qb = $this->qb->resetQueryParts(); + $this->qb->select('lat', 'lng') + ->from('maps_address_geo') + ->where($this->qb->expr()->eq('looked_up', $this->qb->createNamedParameter(true, IQueryBuilder::PARAM_BOOL))) + ->andWhere($this->qb->expr()->eq('adr_norm', $this->qb->createNamedParameter($adr_norm, IQueryBuilder::PARAM_STR))); + $req = $this->qb->execute(); + while ($row = $req->fetch()) { + $res[0] = $row['lat']; + $res[1] = $row['lng']; + $res[2] = true; + } + $req->closeCursor(); + $qb = $this->qb->resetQueryParts(); - return $res; - } + return $res; + } - // looks up the address on external provider returns lat, lon, lookupstate - // do lookup only if last one occured more than one second ago - private function lookupAddressExternal($adr): array { - if (time() - intval($this->memcache->get('lastAddressLookup')) >= 1) { - $opts = [ - 'http' => [ - 'method' => 'GET', - 'user_agent' => 'Nextcloud Maps app', - ] - ]; - $context = stream_context_create($opts); + // looks up the address on external provider returns lat, lon, lookupstate + // do lookup only if last one occured more than one second ago + private function lookupAddressExternal($adr): array { + if (time() - intval($this->memcache->get('lastAddressLookup')) >= 1) { + $opts = [ + 'http' => [ + 'method' => 'GET', + 'user_agent' => 'Nextcloud Maps app', + ] + ]; + $context = stream_context_create($opts); - // we get rid of "post office box" field - $splitted_adr = explode(';', $adr); - if (count($splitted_adr) > 2) { - array_shift($splitted_adr); - } + // we get rid of "post office box" field + $splitted_adr = explode(';', $adr); + if (count($splitted_adr) > 2) { + array_shift($splitted_adr); + } - // remove blank lines (#706) - $splitted_adr = array_filter(array_map('trim', $splitted_adr)); - $query_adr = implode(', ', $splitted_adr); + // remove blank lines (#706) + $splitted_adr = array_filter(array_map('trim', $splitted_adr)); + $query_adr = implode(', ', $splitted_adr); - $result_json = @file_get_contents( - 'https://nominatim.openstreetmap.org/search.php?q='.urlencode($query_adr).'&format=json', - false, - $context - ); - if ($result_json !== false) { - $result = \json_decode($result_json, true); - if (!(key_exists('request_failed', $result) AND $result['request_failed'])) { - $this->logger->debug('External looked up address: ' . $adr . ' with result' . print_r($result, true)); - $this->memcache->set('lastAddressLookup', time()); - $lat = null; - $lon = null; - foreach ($result as $addr) { - if (key_exists('lat', $addr) AND - key_exists('lon', $addr) - ) { - if (is_null($lat) OR - (key_exists('class', $addr) AND - ($addr['class'] == "building" OR $addr['class'] == "place"))) { - $lat = $addr['lat']; - $lon = $addr['lon']; - } - } - } - return [$lat, $lon, true]; - } - } - $this->logger->debug('Externally looked failed'); - } - return [null, null, False]; - } + $result_json = @file_get_contents( + 'https://nominatim.openstreetmap.org/search.php?q='.urlencode($query_adr).'&format=json', + false, + $context + ); + if ($result_json !== false) { + $result = \json_decode($result_json, true); + if (!(key_exists('request_failed', $result) and $result['request_failed'])) { + $this->logger->debug('External looked up address: ' . $adr . ' with result' . print_r($result, true)); + $this->memcache->set('lastAddressLookup', time()); + $lat = null; + $lon = null; + foreach ($result as $addr) { + if (key_exists('lat', $addr) and + key_exists('lon', $addr) + ) { + if (is_null($lat) or + (key_exists('class', $addr) and + ($addr['class'] == 'building' or $addr['class'] == 'place'))) { + $lat = $addr['lat']; + $lon = $addr['lon']; + } + } + } + return [$lat, $lon, true]; + } + } + $this->logger->debug('Externally looked failed'); + } + return [null, null, false]; + } - // launch lookup for all addresses of the vCard - public function scheduleVCardForLookup($cardData, $cardUri) { - $vCard = Reader::read($cardData); + // launch lookup for all addresses of the vCard + public function scheduleVCardForLookup($cardData, $cardUri) { + $vCard = Reader::read($cardData); - $this->cleanUpDBContactAddresses($vCard, $cardUri); + $this->cleanUpDBContactAddresses($vCard, $cardUri); - foreach ($vCard->children() as $property) { - if ($property->name === 'ADR') { - $adr = $property->getValue(); - if ($adr !== ';;;;;;') { - $this->lookupAddress($property->getValue(), $cardUri); - } - } - } - } + foreach ($vCard->children() as $property) { + if ($property->name === 'ADR') { + $adr = $property->getValue(); + if ($adr !== ';;;;;;') { + $this->lookupAddress($property->getValue(), $cardUri); + } + } + } + } - private function cleanUpDBContactAddresses($vCard, $uri) { - $qb = $this->qb; - // get all vcard addresses - $vCardAddresses = []; - foreach ($vCard->children() as $property) { - if ($property->name === 'ADR') { - $adr = $property->getValue(); - array_push($vCardAddresses, $adr); - } - } - // check which addresses from DB is not in the vCard anymore - $adrIdToDelete = []; - $this->qb->select('id', 'adr') - ->from('maps_address_geo') - ->where($this->qb->expr()->eq('object_uri', $this->qb->createNamedParameter($uri, IQueryBuilder::PARAM_STR))); - $req = $this->qb->execute(); - while ($row = $req->fetch()) { - if (!in_array($row['adr'], $vCardAddresses)) { - array_push($adrIdToDelete, $row['id']); - } - } - $req->closeCursor(); - $qb = $this->qb->resetQueryParts(); + private function cleanUpDBContactAddresses($vCard, $uri) { + $qb = $this->qb; + // get all vcard addresses + $vCardAddresses = []; + foreach ($vCard->children() as $property) { + if ($property->name === 'ADR') { + $adr = $property->getValue(); + array_push($vCardAddresses, $adr); + } + } + // check which addresses from DB is not in the vCard anymore + $adrIdToDelete = []; + $this->qb->select('id', 'adr') + ->from('maps_address_geo') + ->where($this->qb->expr()->eq('object_uri', $this->qb->createNamedParameter($uri, IQueryBuilder::PARAM_STR))); + $req = $this->qb->execute(); + while ($row = $req->fetch()) { + if (!in_array($row['adr'], $vCardAddresses)) { + array_push($adrIdToDelete, $row['id']); + } + } + $req->closeCursor(); + $qb = $this->qb->resetQueryParts(); - foreach ($adrIdToDelete as $id) { - $qb->delete('maps_address_geo') - ->where( - $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - } + foreach ($adrIdToDelete as $id) { + $qb->delete('maps_address_geo') + ->where( + $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + } - public function deleteDBContactAddresses($uri) { - $qb = $this->qb; - $qb->delete('maps_address_geo') - ->where( - $qb->expr()->eq('object_uri', $qb->createNamedParameter($uri, IQueryBuilder::PARAM_STR)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } + public function deleteDBContactAddresses($uri) { + $qb = $this->qb; + $qb->delete('maps_address_geo') + ->where( + $qb->expr()->eq('object_uri', $qb->createNamedParameter($uri, IQueryBuilder::PARAM_STR)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } - // schedules the address for an external lookup - private function scheduleForLookup($adr, $uri): array { - $geo = $this->lookupAddressInternal($adr); - // if not found internally, ask external service - if (!$geo[2]) { - $geo = $this->lookupAddressExternal($adr); - } - $adr_norm = strtolower(preg_replace('/\s+/', '', $adr)); - $this->qb->insert('maps_address_geo') - ->values([ - 'adr' => $this->qb->createNamedParameter($adr, IQueryBuilder::PARAM_STR), - 'adr_norm' => $this->qb->createNamedParameter($adr_norm, IQueryBuilder::PARAM_STR), - 'object_uri' => $this->qb->createNamedParameter($uri, IQueryBuilder::PARAM_STR), - 'lat' => $this->qb->createNamedParameter($geo[0], IQueryBuilder::PARAM_STR), - 'lng' => $this->qb->createNamedParameter($geo[1], IQueryBuilder::PARAM_STR), - 'looked_up' => $this->qb->createNamedParameter($geo[2], IQueryBuilder::PARAM_BOOL), - ]); - $req = $this->qb->execute(); - $id = $this->qb->getLastInsertId(); - $qb = $this->qb->resetQueryParts(); - if (!$geo[2]) { - $this->jobList->add(LookupMissingGeoJob::class, []); - } - return [$id, $geo[0], $geo[1], $geo[2]]; - } + // schedules the address for an external lookup + private function scheduleForLookup($adr, $uri): array { + $geo = $this->lookupAddressInternal($adr); + // if not found internally, ask external service + if (!$geo[2]) { + $geo = $this->lookupAddressExternal($adr); + } + $adr_norm = strtolower(preg_replace('/\s+/', '', $adr)); + $this->qb->insert('maps_address_geo') + ->values([ + 'adr' => $this->qb->createNamedParameter($adr, IQueryBuilder::PARAM_STR), + 'adr_norm' => $this->qb->createNamedParameter($adr_norm, IQueryBuilder::PARAM_STR), + 'object_uri' => $this->qb->createNamedParameter($uri, IQueryBuilder::PARAM_STR), + 'lat' => $this->qb->createNamedParameter($geo[0], IQueryBuilder::PARAM_STR), + 'lng' => $this->qb->createNamedParameter($geo[1], IQueryBuilder::PARAM_STR), + 'looked_up' => $this->qb->createNamedParameter($geo[2], IQueryBuilder::PARAM_BOOL), + ]); + $req = $this->qb->execute(); + $id = $this->qb->getLastInsertId(); + $qb = $this->qb->resetQueryParts(); + if (!$geo[2]) { + $this->jobList->add(LookupMissingGeoJob::class, []); + } + return [$id, $geo[0], $geo[1], $geo[2]]; + } - // looks up the geo information which have not been looked up - // this is called by the Cron job - public function lookupMissingGeo($max=200):bool { - // stores if all addresses where looked up - $lookedUpAll = true; - $this->qb->select('adr', 'object_uri') - ->from('maps_address_geo') - ->where($this->qb->expr()->eq('looked_up', $this->qb->createNamedParameter(False, IQueryBuilder::PARAM_BOOL))) - ->setMaxResults($max); - $req = $this->qb->execute(); - $result = $req->fetchAll(); - $req->closeCursor(); - $i = 0; - foreach ($result as $row) { - $i++; - $geo = $this->lookupAddress($row['adr'], $row['object_uri']); - // lookup failed - if (!$geo[2]){ - $lookedUpAll = false; - } - \sleep(1); - \usleep(\rand(100,100000)); - } - // not all addresses where loaded from database - if ($i === $max){ - $lookedUpAll = false; - } - if ($lookedUpAll){ - $this->logger->debug('Successfully looked up all addresses during cron job'); - } else { - $this->logger->debug('Failed to look up all addresses during cron job'); - } - return $lookedUpAll; - } + // looks up the geo information which have not been looked up + // this is called by the Cron job + public function lookupMissingGeo($max = 200):bool { + // stores if all addresses where looked up + $lookedUpAll = true; + $this->qb->select('adr', 'object_uri') + ->from('maps_address_geo') + ->where($this->qb->expr()->eq('looked_up', $this->qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL))) + ->setMaxResults($max); + $req = $this->qb->execute(); + $result = $req->fetchAll(); + $req->closeCursor(); + $i = 0; + foreach ($result as $row) { + $i++; + $geo = $this->lookupAddress($row['adr'], $row['object_uri']); + // lookup failed + if (!$geo[2]) { + $lookedUpAll = false; + } + \sleep(1); + \usleep(\rand(100, 100000)); + } + // not all addresses where loaded from database + if ($i === $max) { + $lookedUpAll = false; + } + if ($lookedUpAll) { + $this->logger->debug('Successfully looked up all addresses during cron job'); + } else { + $this->logger->debug('Failed to look up all addresses during cron job'); + } + return $lookedUpAll; + } } diff --git a/lib/Service/DevicesService.php b/lib/Service/DevicesService.php index abb6dc2a4..c7cd9340f 100644 --- a/lib/Service/DevicesService.php +++ b/lib/Service/DevicesService.php @@ -13,56 +13,56 @@ namespace OCA\Maps\Service; use OCP\DB\Exception; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Files\NotFoundException; +use OCP\IDBConnection; use OCP\IL10N; use OCP\ILogger; -use OCP\IDBConnection; -use OCP\DB\QueryBuilder\IQueryBuilder; class DevicesService { - private $l10n; - private $logger; - private $qb; - private $dbconnection; - private $importUserId; - private $currentXmlTag; - private $importDevName; - private $importFileName; - private $currentPoint; - private $currentPointList; - private $trackIndex; - private $pointIndex; - private $insideTrk; - - public function __construct (ILogger $logger, IL10N $l10n, IDBConnection $dbconnection) { - $this->l10n = $l10n; - $this->logger = $logger; - $this->dbconnection = $dbconnection; - $this->qb = $dbconnection->getQueryBuilder(); - } - - private function db_quote_escape_string($str){ - return $this->dbconnection->quote($str); - } - - /** - * @param string $userId - * @param int $pruneBefore - * @return array with devices - */ - public function getDevicesFromDB($userId) { - $devices = []; - $qb = $this->qb; - $qb->select('id', 'user_agent', 'color') - ->from('maps_devices', 'd') - ->where( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - $req = $qb->execute(); - - while ($row = $req->fetch()) { - $devices[intval($row['id'])] = [ + private $l10n; + private $logger; + private $qb; + private $dbconnection; + private $importUserId; + private $currentXmlTag; + private $importDevName; + private $importFileName; + private $currentPoint; + private $currentPointList; + private $trackIndex; + private $pointIndex; + private $insideTrk; + + public function __construct(ILogger $logger, IL10N $l10n, IDBConnection $dbconnection) { + $this->l10n = $l10n; + $this->logger = $logger; + $this->dbconnection = $dbconnection; + $this->qb = $dbconnection->getQueryBuilder(); + } + + private function db_quote_escape_string($str) { + return $this->dbconnection->quote($str); + } + + /** + * @param string $userId + * @param int $pruneBefore + * @return array with devices + */ + public function getDevicesFromDB($userId) { + $devices = []; + $qb = $this->qb; + $qb->select('id', 'user_agent', 'color') + ->from('maps_devices', 'd') + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + $req = $qb->execute(); + + while ($row = $req->fetch()) { + $devices[intval($row['id'])] = [ 'id' => intval($row['id']), 'user_agent' => $row['user_agent'], 'color' => $row['color'], @@ -70,13 +70,13 @@ public function getDevicesFromDB($userId) { 'isDeleteable' => true, 'isUpdateable' => true, 'isReadable' => true, - 'shares' => array() + 'shares' => [] ]; - } - $req->closeCursor(); - $qb = $qb->resetQueryParts(); - return $devices; - } + } + $req->closeCursor(); + $qb = $qb->resetQueryParts(); + return $devices; + } /** * @param string[] $tokens @@ -106,7 +106,7 @@ public function getDevicesByTokens(array $tokens) { 'isDeleteable' => true, 'isUpdateable' => false, 'isReadable' => true, - 'shares' => array(), + 'shares' => [], 'tokens' => [$row['token']] ]; } @@ -125,35 +125,35 @@ public function getDevicesByTokens(array $tokens) { * @return array * @throws \OCP\DB\Exception */ - public function getDevicePointsFromDB($userId, $deviceId, ?int $pruneBefore=0, ?int $limit=null, ?int $offset=null) { - $qb = $this->qb; - // get coordinates - $qb->selectDistinct(['p.id', 'lat', 'lng', 'timestamp', 'altitude', 'accuracy', 'battery']) - ->from('maps_device_points', 'p') - ->innerJoin('p', 'maps_devices', 'd', $qb->expr()->eq('d.id', 'p.device_id')) - ->where( - $qb->expr()->eq('p.device_id', $qb->createNamedParameter($deviceId, IQueryBuilder::PARAM_INT)) - ) - ->andWhere( - $qb->expr()->eq('d.user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - if (intval($pruneBefore) > 0) { - $qb->andWhere( - $qb->expr()->gt('timestamp', $qb->createNamedParameter(intval($pruneBefore), IQueryBuilder::PARAM_INT)) - ); - } + public function getDevicePointsFromDB($userId, $deviceId, ?int $pruneBefore = 0, ?int $limit = null, ?int $offset = null) { + $qb = $this->qb; + // get coordinates + $qb->selectDistinct(['p.id', 'lat', 'lng', 'timestamp', 'altitude', 'accuracy', 'battery']) + ->from('maps_device_points', 'p') + ->innerJoin('p', 'maps_devices', 'd', $qb->expr()->eq('d.id', 'p.device_id')) + ->where( + $qb->expr()->eq('p.device_id', $qb->createNamedParameter($deviceId, IQueryBuilder::PARAM_INT)) + ) + ->andWhere( + $qb->expr()->eq('d.user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + if (intval($pruneBefore) > 0) { + $qb->andWhere( + $qb->expr()->gt('timestamp', $qb->createNamedParameter(intval($pruneBefore), IQueryBuilder::PARAM_INT)) + ); + } if (!is_null($offset)) { $qb->setFirstResult($offset); } if (!is_null($limit)) { $qb->setMaxResults($limit); } - $qb->orderBy('timestamp', 'DESC'); - $req = $qb->execute(); + $qb->orderBy('timestamp', 'DESC'); + $req = $qb->execute(); - $points = []; - while ($row = $req->fetch()) { - $points[] = [ + $points = []; + while ($row = $req->fetch()) { + $points[] = [ 'id' => intval($row['id']), 'lat' => floatval($row['lat']), 'lng' => floatval($row['lng']), @@ -162,12 +162,12 @@ public function getDevicePointsFromDB($userId, $deviceId, ?int $pruneBefore=0, ? 'accuracy' => is_numeric($row['accuracy']) ? floatval($row['accuracy']) : null, 'battery' => is_numeric($row['battery']) ? floatval($row['battery']) : null ]; - } - $req->closeCursor(); - $qb = $qb->resetQueryParts(); + } + $req->closeCursor(); + $qb = $qb->resetQueryParts(); - return array_reverse($points); - } + return array_reverse($points); + } /** * @param string[] $token @@ -177,11 +177,11 @@ public function getDevicePointsFromDB($userId, $deviceId, ?int $pruneBefore=0, ? * @return array * @throws Exception */ - public function getDevicePointsByTokens(array $tokens, ?int $pruneBefore=0, ?int $limit=10000, ?int $offset=0) { + public function getDevicePointsByTokens(array $tokens, ?int $pruneBefore = 0, ?int $limit = 10000, ?int $offset = 0) { $qb = $this->qb; // get coordinates $or = $qb->expr()->orX(); - foreach($tokens as $token) { + foreach ($tokens as $token) { $and = $qb->expr()->andX(); $and->add($qb->expr()->eq('s.token', $qb->createNamedParameter($token, IQueryBuilder::PARAM_STR))); $and->add($qb->expr()->lte('p.timestamp', 's.timestamp_to')); @@ -255,547 +255,535 @@ public function getDeviceTimePointsFromDb($userId, $deviceId) { return $points; } - public function getOrCreateDeviceFromDB($userId, $userAgent) { - $deviceId = null; - $qb = $this->qb; - $qb->select('id') - ->from('maps_devices', 'd') - ->where( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ) - ->andWhere( - $qb->expr()->eq('user_agent', $qb->createNamedParameter($userAgent, IQueryBuilder::PARAM_STR)) - ); - $req = $qb->execute(); - - while ($row = $req->fetch()) { - $deviceId = intval($row['id']); - break; - } - $req->closeCursor(); - $qb = $qb->resetQueryParts(); - - if ($deviceId === null) { - $qb->insert('maps_devices') - ->values([ - 'user_agent' => $qb->createNamedParameter($userAgent, IQueryBuilder::PARAM_STR), - 'user_id' => $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR) - ]); - $req = $qb->execute(); - $deviceId = $qb->getLastInsertId(); - $qb = $qb->resetQueryParts(); - } - return $deviceId; - } - - public function addPointToDB($deviceId, $lat, $lng, $ts, $altitude, $battery, $accuracy) { - $qb = $this->qb; - $qb->insert('maps_device_points') - ->values([ - 'device_id' => $qb->createNamedParameter($deviceId, IQueryBuilder::PARAM_STR), - 'lat' => $qb->createNamedParameter($lat, IQueryBuilder::PARAM_STR), - 'lng' => $qb->createNamedParameter($lng, IQueryBuilder::PARAM_STR), - 'timestamp' => $qb->createNamedParameter(intval($ts), IQueryBuilder::PARAM_INT), - 'altitude' => $qb->createNamedParameter(is_numeric($altitude) ? $altitude : null, IQueryBuilder::PARAM_STR), - 'battery' => $qb->createNamedParameter(is_numeric($battery) ? $battery : null, IQueryBuilder::PARAM_STR), - 'accuracy' => $qb->createNamedParameter(is_numeric($accuracy) ? $accuracy : null, IQueryBuilder::PARAM_STR) - ]); - $req = $qb->execute(); - $pointId = $qb->getLastInsertId(); - $qb = $qb->resetQueryParts(); - return $pointId; - } - - public function addPointsToDB($deviceId, $points) { - $values = []; - foreach ($points as $p) { - $value = '('. - $this->db_quote_escape_string($deviceId).', '. - $this->db_quote_escape_string($p['lat']).', '. - $this->db_quote_escape_string($p['lng']).', '. - $this->db_quote_escape_string($p['date']).', '. - ((isset($p['altitude']) and is_numeric($p['altitude'])) ? $this->db_quote_escape_string(floatval($p['altitude'])) : 'NULL').', '. - ((isset($p['battery']) and is_numeric($p['battery'])) ? $this->db_quote_escape_string(floatval($p['battery'])) : 'NULL').', '. - ((isset($p['accuracy']) and is_numeric($p['accuracy'])) ? $this->db_quote_escape_string(floatval($p['accuracy'])) : 'NULL').')'; - array_push($values, $value); - } - $valuesStr = implode(', ', $values); - $sql = ' + public function getOrCreateDeviceFromDB($userId, $userAgent) { + $deviceId = null; + $qb = $this->qb; + $qb->select('id') + ->from('maps_devices', 'd') + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ) + ->andWhere( + $qb->expr()->eq('user_agent', $qb->createNamedParameter($userAgent, IQueryBuilder::PARAM_STR)) + ); + $req = $qb->execute(); + + while ($row = $req->fetch()) { + $deviceId = intval($row['id']); + break; + } + $req->closeCursor(); + $qb = $qb->resetQueryParts(); + + if ($deviceId === null) { + $qb->insert('maps_devices') + ->values([ + 'user_agent' => $qb->createNamedParameter($userAgent, IQueryBuilder::PARAM_STR), + 'user_id' => $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR) + ]); + $req = $qb->execute(); + $deviceId = $qb->getLastInsertId(); + $qb = $qb->resetQueryParts(); + } + return $deviceId; + } + + public function addPointToDB($deviceId, $lat, $lng, $ts, $altitude, $battery, $accuracy) { + $qb = $this->qb; + $qb->insert('maps_device_points') + ->values([ + 'device_id' => $qb->createNamedParameter($deviceId, IQueryBuilder::PARAM_STR), + 'lat' => $qb->createNamedParameter($lat, IQueryBuilder::PARAM_STR), + 'lng' => $qb->createNamedParameter($lng, IQueryBuilder::PARAM_STR), + 'timestamp' => $qb->createNamedParameter(intval($ts), IQueryBuilder::PARAM_INT), + 'altitude' => $qb->createNamedParameter(is_numeric($altitude) ? $altitude : null, IQueryBuilder::PARAM_STR), + 'battery' => $qb->createNamedParameter(is_numeric($battery) ? $battery : null, IQueryBuilder::PARAM_STR), + 'accuracy' => $qb->createNamedParameter(is_numeric($accuracy) ? $accuracy : null, IQueryBuilder::PARAM_STR) + ]); + $req = $qb->execute(); + $pointId = $qb->getLastInsertId(); + $qb = $qb->resetQueryParts(); + return $pointId; + } + + public function addPointsToDB($deviceId, $points) { + $values = []; + foreach ($points as $p) { + $value = '('. + $this->db_quote_escape_string($deviceId).', '. + $this->db_quote_escape_string($p['lat']).', '. + $this->db_quote_escape_string($p['lng']).', '. + $this->db_quote_escape_string($p['date']).', '. + ((isset($p['altitude']) and is_numeric($p['altitude'])) ? $this->db_quote_escape_string(floatval($p['altitude'])) : 'NULL').', '. + ((isset($p['battery']) and is_numeric($p['battery'])) ? $this->db_quote_escape_string(floatval($p['battery'])) : 'NULL').', '. + ((isset($p['accuracy']) and is_numeric($p['accuracy'])) ? $this->db_quote_escape_string(floatval($p['accuracy'])) : 'NULL').')'; + array_push($values, $value); + } + $valuesStr = implode(', ', $values); + $sql = ' INSERT INTO *PREFIX*maps_device_points (device_id, lat, lng, timestamp, altitude, battery, accuracy) VALUES '.$valuesStr.' ;'; - $req = $this->dbconnection->prepare($sql); - $req->execute(); - $req->closeCursor(); - } - - public function getDeviceFromDB($id, $userId) { - $device = null; - $qb = $this->qb; - $qb->select('id', 'user_agent', 'color') - ->from('maps_devices', 'd') - ->where( - $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) - ); - if ($userId !== null) { - $qb->andWhere( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - } - $req = $qb->execute(); - - while ($row = $req->fetch()) { - $device = [ - 'id' => intval($row['id']), - 'user_agent' => $row['user_agent'], - 'color' => $row['color'] - ]; - break; - } - $req->closeCursor(); - $qb = $qb->resetQueryParts(); - return $device; - } - - public function editDeviceInDB($id, $color, $name) { - $qb = $this->qb; - $qb->update('maps_devices'); - if (is_string($color) && strlen($color) > 0) { - $qb->set('color', $qb->createNamedParameter($color, IQueryBuilder::PARAM_STR)); - } - if (is_string($name) && strlen($name) > 0) { - $qb->set('user_agent', $qb->createNamedParameter($name, IQueryBuilder::PARAM_STR)); - } - $qb->where( - $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - - public function deleteDeviceFromDB($id) { - $qb = $this->qb; - $qb->delete('maps_devices') - ->where( - $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - - $qb->delete('maps_device_points') - ->where( - $qb->expr()->eq('device_id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - - public function countPoints($userId, $deviceIdList, $begin, $end) { - $qb = $this->qb; - $qb->select($qb->createFunction('COUNT(*) AS co')) - ->from('maps_devices', 'd') - ->innerJoin('d', 'maps_device_points', 'p', $qb->expr()->eq('d.id', 'p.device_id')) - ->where( - $qb->expr()->eq('d.user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - if (is_array($deviceIdList) and count($deviceIdList) > 0) { - $or = $qb->expr()->orx(); - foreach ($deviceIdList as $deviceId) { - $or->add($qb->expr()->eq('d.id', $qb->createNamedParameter($deviceId, IQueryBuilder::PARAM_INT))); - } - $qb->andWhere($or); - } - else { - return 0; - } - if ($begin !== null && is_numeric($begin)) { - $qb->andWhere( - $qb->expr()->gt('p.timestamp', $qb->createNamedParameter(intval($begin), IQueryBuilder::PARAM_INT)) - ); - } - if ($end !== null && is_numeric($end)) { - $qb->andWhere( - $qb->expr()->lt('p.timestamp', $qb->createNamedParameter(intval($end), IQueryBuilder::PARAM_INT)) - ); - } - $req = $qb->execute(); - $count = 0; - while ($row = $req->fetch()) { - $count = intval($row['co']); - break; - } - $qb = $qb->resetQueryParts(); - - return $count; - } - - public function exportDevices($userId, $handler, $deviceIdList, $begin, $end, $appVersion, $filename) { - $gpxHeader = $this->generateGpxHeader($filename, $appVersion, count($deviceIdList)); - fwrite($handler, $gpxHeader); - - foreach ($deviceIdList as $devid) { - $nbPoints = $this->countPoints($userId, [$devid], $begin, $end); - if ($nbPoints > 0) { - $this->getAndWriteDevicePoints($devid, $begin, $end, $handler, $nbPoints, $userId); - } - } - fwrite($handler, ''); - } - - private function generateGpxHeader($name, $appVersion, $nbdev=0) { - date_default_timezone_set('UTC'); - $dt = new \DateTime(); - $date = $dt->format('Y-m-d\TH:i:s\Z'); - $gpxText = '' . "\n"; - $gpxText .= '' . "\n"; - $gpxText .= '' . "\n" . ' ' . "\n"; - $gpxText .= ' ' . $name . '' . "\n"; - if ($nbdev > 0) { - $gpxText .= ' ' . $nbdev . ' device'.($nbdev > 1 ? 's' : '').'' . "\n"; - } - $gpxText .= '' . "\n"; - return $gpxText; - } - - private function getAndWriteDevicePoints($devid, $begin, $end, $fd, $nbPoints, $userId) { - $device = $this->getDeviceFromDB($devid, $userId); - $devname = $device['user_agent']; - $qb = $this->qb; - - $gpxText = '' . "\n" . ' ' . $devname . '' . "\n"; - $gpxText .= ' ' . "\n"; - fwrite($fd, $gpxText); - - $chunkSize = 10000; - $pointIndex = 0; - - while ($pointIndex < $nbPoints) { - $gpxText = ''; - $qb->select('id', 'lat', 'lng', 'timestamp', 'altitude', 'accuracy', 'battery') - ->from('maps_device_points', 'p') - ->where( - $qb->expr()->eq('device_id', $qb->createNamedParameter($devid, IQueryBuilder::PARAM_INT)) - ); - if (intval($begin) > 0) { - $qb->andWhere( - $qb->expr()->gt('timestamp', $qb->createNamedParameter(intval($begin), IQueryBuilder::PARAM_INT)) - ); - } - if (intval($end) > 0) { - $qb->andWhere( - $qb->expr()->lt('timestamp', $qb->createNamedParameter(intval($end), IQueryBuilder::PARAM_INT)) - ); - } - $qb->setFirstResult($pointIndex); - $qb->setMaxResults($chunkSize); - $qb->orderBy('timestamp', 'ASC'); - $req = $qb->execute(); - - while ($row = $req->fetch()) { - $id = intval($row['id']); - $lat = floatval($row['lat']); - $lng = floatval($row['lng']); - $epoch = $row['timestamp']; - $date = ''; - if (is_numeric($epoch)) { - $epoch = intval($epoch); - $dt = new \DateTime("@$epoch"); - $date = $dt->format('Y-m-d\TH:i:s\Z'); - } - $alt = $row['altitude']; - $acc = $row['accuracy']; - $bat = $row['battery']; - - $gpxExtension = ''; - $gpxText .= ' ' . "\n"; - $gpxText .= ' ' . "\n"; - if (is_numeric($alt)) { - $gpxText .= ' ' . sprintf('%.2f', floatval($alt)) . '' . "\n"; - } - if (is_numeric($acc) && intval($acc) >= 0) { - $gpxExtension .= ' ' . sprintf('%.2f', floatval($acc)) . '' . "\n"; - } - if (is_numeric($bat) && intval($bat) >= 0) { - $gpxExtension .= ' ' . sprintf('%.2f', floatval($bat)) . '' . "\n"; - } - if ($gpxExtension !== '') { - $gpxText .= ' '. "\n" . $gpxExtension; - $gpxText .= ' ' . "\n"; - } - $gpxText .= ' ' . "\n"; - } - $req->closeCursor(); - $qb = $qb->resetQueryParts(); - - // write the chunk - fwrite($fd, $gpxText); - $pointIndex = $pointIndex + $chunkSize; - } - $gpxText = ' ' . "\n"; - $gpxText .= '' . "\n"; - fwrite($fd, $gpxText); - } - - public function importDevices($userId, $file) { - $lowerFileName = strtolower($file->getName()); - if ($this->endswith($lowerFileName, '.gpx')) { - return $this->importDevicesFromGpx($userId, $file); - } - elseif ($this->endswith($lowerFileName, '.kml')) { - $fp = $file->fopen('r'); - $name = $file->getName(); - return $this->importDevicesFromKml($userId, $fp, $name); - } - elseif ($this->endswith($lowerFileName, '.kmz')) { - return $this->importDevicesFromKmz($userId, $file); - } - } - - public function importDevicesFromGpx($userId, $file) { - $this->currentPointList = []; - $this->importUserId = $userId; - $this->importFileName = $file->getName(); - $this->trackIndex = 1; - $this->insideTrk = false; - - $xml_parser = xml_parser_create(); - xml_set_object($xml_parser, $this); - xml_set_element_handler($xml_parser, 'gpxStartElement', 'gpxEndElement'); - xml_set_character_data_handler($xml_parser, 'gpxDataElement'); - - $fp = $file->fopen('r'); - - // using xml_parse to be able to parse file chunks in case it's too big - while ($data = fread($fp, 4096000)) { - if (!xml_parse($xml_parser, $data, feof($fp))) { - $this->logger->error( - 'Exception in '.$file->getName().' parsing at line '. - xml_get_current_line_number($xml_parser).' : '. - xml_error_string(xml_get_error_code($xml_parser)), - array('app' => 'maps') - ); - return 0; - } - } - fclose($fp); - xml_parser_free($xml_parser); - - return ($this->trackIndex - 1); - } - - private function gpxStartElement($parser, $name, $attrs) { - //$points, array($lat, $lon, $ele, $timestamp, $acc, $bat, $sat, $ua, $speed, $bearing) - $this->currentXmlTag = $name; - if ($name === 'TRK') { - $this->importDevName = ''; - $this->pointIndex = 1; - $this->currentPointList = []; - $this->insideTrk = true; - } - else if ($name === 'TRKPT') { - $this->currentPoint = []; - if (isset($attrs['LAT'])) { - $this->currentPoint['lat'] = floatval($attrs['LAT']); - } - if (isset($attrs['LON'])) { - $this->currentPoint['lng'] = floatval($attrs['LON']); - } - } - //var_dump($attrs); - } - - private function gpxEndElement($parser, $name) { - if ($name === 'TRK') { - $this->insideTrk = false; - // log last track points - if (count($this->currentPointList) > 0) { - if ($this->importDevName === '') { - $this->importDevName = $this->importFileName.' '.$this->trackIndex; - } - $devid = $this->getOrCreateDeviceFromDB($this->importUserId, $this->importDevName); - $this->addPointsToDB($devid, $this->currentPointList); - } - $this->trackIndex++; - unset($this->currentPointList); - } - else if ($name === 'TRKPT') { - // store track point - - // convert date - if (isset($this->currentPoint['date'])) { - $time = new \DateTime($this->currentPoint['date']); - $timestamp = $time->getTimestamp(); - $this->currentPoint['date'] = $timestamp; - } - array_push($this->currentPointList, $this->currentPoint); - // if we have enough points, we log them and clean the points array - if (count($this->currentPointList) >= 500) { - if ($this->importDevName === '') { - $this->importDevName = 'device'.$this->trackIndex; - } - $devid = $this->getOrCreateDeviceFromDB($this->importUserId, $this->importDevName); - $this->addPointsToDB($devid, $this->currentPointList); - unset($this->currentPointList); - $this->currentPointList = array(); - } - $this->pointIndex++; - } - } - - private function gpxDataElement($parser, $data) { - $d = trim($data); - if (!empty($d)) { - if ($this->currentXmlTag === 'ELE') { - $this->currentPoint['altitude'] = (isset($this->currentPoint['altitude'])) ? $this->currentPoint['altitude'].$d : $d; - } - else if ($this->currentXmlTag === 'BATTERYLEVEL') { - $this->currentPoint['battery'] = (isset($this->currentPoint['battery'])) ? $this->currentPoint['battery'].$d : $d; - } - else if ($this->currentXmlTag === 'ACCURACY') { - $this->currentPoint['accuracy'] = (isset($this->currentPoint['accuracy'])) ? $this->currentPoint['accuracy'].$d : $d; - } - else if ($this->insideTrk and $this->currentXmlTag === 'TIME') { - $this->currentPoint['date'] = (isset($this->currentPoint['date'])) ? $this->currentPoint['date'].$d : $d; - } - else if ($this->insideTrk and $this->currentXmlTag === 'NAME') { - $this->importDevName = $this->importDevName . $d; - } - } - } - - public function importDevicesFromKmz($userId, $file) { - $path = $file->getStorage()->getLocalFile($file->getInternalPath()); - $name = $file->getName(); - $zf = new ZIP($path); - if (count($zf->getFiles()) > 0) { - $zippedFilePath = $zf->getFiles()[0]; - $fstream = $zf->getStream($zippedFilePath, 'r'); - - $nbImported = $this->importDevicesFromKml($userId, $fstream, $name); - } - else { - $nbImported = 0; - } - return $nbImported; - } - - public function importDevicesFromKml($userId, $fp, $name) { - $this->trackIndex = 1; - $this->importUserId = $userId; - $this->importFileName = $name; - $xml_parser = xml_parser_create(); - xml_set_object($xml_parser, $this); - xml_set_element_handler($xml_parser, 'kmlStartElement', 'kmlEndElement'); - xml_set_character_data_handler($xml_parser, 'kmlDataElement'); - - while ($data = fread($fp, 4096000)) { - if (!xml_parse($xml_parser, $data, feof($fp))) { - $this->logger->error( - 'Exception in '.$name.' parsing at line '. - xml_get_current_line_number($xml_parser).' : '. - xml_error_string(xml_get_error_code($xml_parser)), - array('app' => $this->appName) - ); - return 0; - } - } - fclose($fp); - xml_parser_free($xml_parser); - return ($this->trackIndex - 1); - } - - private function kmlStartElement($parser, $name, $attrs) { - $this->currentXmlTag = $name; - if ($name === 'GX:TRACK') { - if (isset($attrs['ID'])) { - $this->importDevName = $attrs['ID']; - } - else { - $this->importDevName = $this->importFileName.' '.$this->trackIndex; - } - $this->pointIndex = 1; - $this->currentPointList = []; - } - else if ($name === 'WHEN') { - $this->currentPoint = []; - } - //var_dump($attrs); - } - - private function kmlEndElement($parser, $name) { - if ($name === 'GX:TRACK') { - // log last track points - if (count($this->currentPointList) > 0) { - $devid = $this->getOrCreateDeviceFromDB($this->importUserId, $this->importDevName); - $this->addPointsToDB($devid, $this->currentPointList); - } - $this->trackIndex++; - unset($this->currentPointList); - } - else if ($name === 'GX:COORD') { - // convert date - if (isset($this->currentPoint['date'])) { - $time = new \DateTime($this->currentPoint['date']); - $timestamp = $time->getTimestamp(); - $this->currentPoint['date'] = $timestamp; - } - // get latlng - if (isset($this->currentPoint['coords'])) { - $spl = explode(' ', $this->currentPoint['coords']); - if (count($spl) > 1) { - $this->currentPoint['lat'] = floatval($spl[1]); - $this->currentPoint['lng'] = floatval($spl[0]); - if (count($spl) > 2) { - $this->currentPoint['altitude'] = floatval($spl[2]); - } - } - } - // store track point - array_push($this->currentPointList, $this->currentPoint); - // if we have enough points, we log them and clean the points array - if (count($this->currentPointList) >= 500) { - $devid = $this->getOrCreateDeviceFromDB($this->importUserId, $this->importDevName); - $this->addPointsToDB($devid, $this->currentPointList); - unset($this->currentPointList); - $this->currentPointList = []; - } - $this->pointIndex++; - } - } - - private function kmlDataElement($parser, $data) { - $d = trim($data); - if (!empty($d)) { - if ($this->currentXmlTag === 'WHEN') { - $this->currentPoint['date'] = (isset($this->currentPoint['date'])) ? $this->currentPoint['date'].$d : $d; - } - else if ($this->currentXmlTag === 'GX:COORD') { - $this->currentPoint['coords'] = (isset($this->currentPoint['coords'])) ? $this->currentPoint['coords'].$d : $d; - } - } - } - - private function endswith($string, $test) { - $strlen = strlen($string); - $testlen = strlen($test); - if ($testlen > $strlen) return false; - return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0; - } + $req = $this->dbconnection->prepare($sql); + $req->execute(); + $req->closeCursor(); + } + + public function getDeviceFromDB($id, $userId) { + $device = null; + $qb = $this->qb; + $qb->select('id', 'user_agent', 'color') + ->from('maps_devices', 'd') + ->where( + $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) + ); + if ($userId !== null) { + $qb->andWhere( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + } + $req = $qb->execute(); + + while ($row = $req->fetch()) { + $device = [ + 'id' => intval($row['id']), + 'user_agent' => $row['user_agent'], + 'color' => $row['color'] + ]; + break; + } + $req->closeCursor(); + $qb = $qb->resetQueryParts(); + return $device; + } + + public function editDeviceInDB($id, $color, $name) { + $qb = $this->qb; + $qb->update('maps_devices'); + if (is_string($color) && strlen($color) > 0) { + $qb->set('color', $qb->createNamedParameter($color, IQueryBuilder::PARAM_STR)); + } + if (is_string($name) && strlen($name) > 0) { + $qb->set('user_agent', $qb->createNamedParameter($name, IQueryBuilder::PARAM_STR)); + } + $qb->where( + $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + + public function deleteDeviceFromDB($id) { + $qb = $this->qb; + $qb->delete('maps_devices') + ->where( + $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + + $qb->delete('maps_device_points') + ->where( + $qb->expr()->eq('device_id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + + public function countPoints($userId, $deviceIdList, $begin, $end) { + $qb = $this->qb; + $qb->select($qb->createFunction('COUNT(*) AS co')) + ->from('maps_devices', 'd') + ->innerJoin('d', 'maps_device_points', 'p', $qb->expr()->eq('d.id', 'p.device_id')) + ->where( + $qb->expr()->eq('d.user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + if (is_array($deviceIdList) and count($deviceIdList) > 0) { + $or = $qb->expr()->orx(); + foreach ($deviceIdList as $deviceId) { + $or->add($qb->expr()->eq('d.id', $qb->createNamedParameter($deviceId, IQueryBuilder::PARAM_INT))); + } + $qb->andWhere($or); + } else { + return 0; + } + if ($begin !== null && is_numeric($begin)) { + $qb->andWhere( + $qb->expr()->gt('p.timestamp', $qb->createNamedParameter(intval($begin), IQueryBuilder::PARAM_INT)) + ); + } + if ($end !== null && is_numeric($end)) { + $qb->andWhere( + $qb->expr()->lt('p.timestamp', $qb->createNamedParameter(intval($end), IQueryBuilder::PARAM_INT)) + ); + } + $req = $qb->execute(); + $count = 0; + while ($row = $req->fetch()) { + $count = intval($row['co']); + break; + } + $qb = $qb->resetQueryParts(); + + return $count; + } + + public function exportDevices($userId, $handler, $deviceIdList, $begin, $end, $appVersion, $filename) { + $gpxHeader = $this->generateGpxHeader($filename, $appVersion, count($deviceIdList)); + fwrite($handler, $gpxHeader); + + foreach ($deviceIdList as $devid) { + $nbPoints = $this->countPoints($userId, [$devid], $begin, $end); + if ($nbPoints > 0) { + $this->getAndWriteDevicePoints($devid, $begin, $end, $handler, $nbPoints, $userId); + } + } + fwrite($handler, ''); + } + + private function generateGpxHeader($name, $appVersion, $nbdev = 0) { + date_default_timezone_set('UTC'); + $dt = new \DateTime(); + $date = $dt->format('Y-m-d\TH:i:s\Z'); + $gpxText = '' . "\n"; + $gpxText .= '' . "\n"; + $gpxText .= '' . "\n" . ' ' . "\n"; + $gpxText .= ' ' . $name . '' . "\n"; + if ($nbdev > 0) { + $gpxText .= ' ' . $nbdev . ' device'.($nbdev > 1 ? 's' : '').'' . "\n"; + } + $gpxText .= '' . "\n"; + return $gpxText; + } + + private function getAndWriteDevicePoints($devid, $begin, $end, $fd, $nbPoints, $userId) { + $device = $this->getDeviceFromDB($devid, $userId); + $devname = $device['user_agent']; + $qb = $this->qb; + + $gpxText = '' . "\n" . ' ' . $devname . '' . "\n"; + $gpxText .= ' ' . "\n"; + fwrite($fd, $gpxText); + + $chunkSize = 10000; + $pointIndex = 0; + + while ($pointIndex < $nbPoints) { + $gpxText = ''; + $qb->select('id', 'lat', 'lng', 'timestamp', 'altitude', 'accuracy', 'battery') + ->from('maps_device_points', 'p') + ->where( + $qb->expr()->eq('device_id', $qb->createNamedParameter($devid, IQueryBuilder::PARAM_INT)) + ); + if (intval($begin) > 0) { + $qb->andWhere( + $qb->expr()->gt('timestamp', $qb->createNamedParameter(intval($begin), IQueryBuilder::PARAM_INT)) + ); + } + if (intval($end) > 0) { + $qb->andWhere( + $qb->expr()->lt('timestamp', $qb->createNamedParameter(intval($end), IQueryBuilder::PARAM_INT)) + ); + } + $qb->setFirstResult($pointIndex); + $qb->setMaxResults($chunkSize); + $qb->orderBy('timestamp', 'ASC'); + $req = $qb->execute(); + + while ($row = $req->fetch()) { + $id = intval($row['id']); + $lat = floatval($row['lat']); + $lng = floatval($row['lng']); + $epoch = $row['timestamp']; + $date = ''; + if (is_numeric($epoch)) { + $epoch = intval($epoch); + $dt = new \DateTime("@$epoch"); + $date = $dt->format('Y-m-d\TH:i:s\Z'); + } + $alt = $row['altitude']; + $acc = $row['accuracy']; + $bat = $row['battery']; + + $gpxExtension = ''; + $gpxText .= ' ' . "\n"; + $gpxText .= ' ' . "\n"; + if (is_numeric($alt)) { + $gpxText .= ' ' . sprintf('%.2f', floatval($alt)) . '' . "\n"; + } + if (is_numeric($acc) && intval($acc) >= 0) { + $gpxExtension .= ' ' . sprintf('%.2f', floatval($acc)) . '' . "\n"; + } + if (is_numeric($bat) && intval($bat) >= 0) { + $gpxExtension .= ' ' . sprintf('%.2f', floatval($bat)) . '' . "\n"; + } + if ($gpxExtension !== '') { + $gpxText .= ' '. "\n" . $gpxExtension; + $gpxText .= ' ' . "\n"; + } + $gpxText .= ' ' . "\n"; + } + $req->closeCursor(); + $qb = $qb->resetQueryParts(); + + // write the chunk + fwrite($fd, $gpxText); + $pointIndex = $pointIndex + $chunkSize; + } + $gpxText = ' ' . "\n"; + $gpxText .= '' . "\n"; + fwrite($fd, $gpxText); + } + + public function importDevices($userId, $file) { + $lowerFileName = strtolower($file->getName()); + if ($this->endswith($lowerFileName, '.gpx')) { + return $this->importDevicesFromGpx($userId, $file); + } elseif ($this->endswith($lowerFileName, '.kml')) { + $fp = $file->fopen('r'); + $name = $file->getName(); + return $this->importDevicesFromKml($userId, $fp, $name); + } elseif ($this->endswith($lowerFileName, '.kmz')) { + return $this->importDevicesFromKmz($userId, $file); + } + } + + public function importDevicesFromGpx($userId, $file) { + $this->currentPointList = []; + $this->importUserId = $userId; + $this->importFileName = $file->getName(); + $this->trackIndex = 1; + $this->insideTrk = false; + + $xml_parser = xml_parser_create(); + xml_set_object($xml_parser, $this); + xml_set_element_handler($xml_parser, 'gpxStartElement', 'gpxEndElement'); + xml_set_character_data_handler($xml_parser, 'gpxDataElement'); + + $fp = $file->fopen('r'); + + // using xml_parse to be able to parse file chunks in case it's too big + while ($data = fread($fp, 4096000)) { + if (!xml_parse($xml_parser, $data, feof($fp))) { + $this->logger->error( + 'Exception in '.$file->getName().' parsing at line '. + xml_get_current_line_number($xml_parser).' : '. + xml_error_string(xml_get_error_code($xml_parser)), + ['app' => 'maps'] + ); + return 0; + } + } + fclose($fp); + xml_parser_free($xml_parser); + + return ($this->trackIndex - 1); + } + + private function gpxStartElement($parser, $name, $attrs) { + //$points, array($lat, $lon, $ele, $timestamp, $acc, $bat, $sat, $ua, $speed, $bearing) + $this->currentXmlTag = $name; + if ($name === 'TRK') { + $this->importDevName = ''; + $this->pointIndex = 1; + $this->currentPointList = []; + $this->insideTrk = true; + } elseif ($name === 'TRKPT') { + $this->currentPoint = []; + if (isset($attrs['LAT'])) { + $this->currentPoint['lat'] = floatval($attrs['LAT']); + } + if (isset($attrs['LON'])) { + $this->currentPoint['lng'] = floatval($attrs['LON']); + } + } + //var_dump($attrs); + } + + private function gpxEndElement($parser, $name) { + if ($name === 'TRK') { + $this->insideTrk = false; + // log last track points + if (count($this->currentPointList) > 0) { + if ($this->importDevName === '') { + $this->importDevName = $this->importFileName.' '.$this->trackIndex; + } + $devid = $this->getOrCreateDeviceFromDB($this->importUserId, $this->importDevName); + $this->addPointsToDB($devid, $this->currentPointList); + } + $this->trackIndex++; + unset($this->currentPointList); + } elseif ($name === 'TRKPT') { + // store track point + + // convert date + if (isset($this->currentPoint['date'])) { + $time = new \DateTime($this->currentPoint['date']); + $timestamp = $time->getTimestamp(); + $this->currentPoint['date'] = $timestamp; + } + array_push($this->currentPointList, $this->currentPoint); + // if we have enough points, we log them and clean the points array + if (count($this->currentPointList) >= 500) { + if ($this->importDevName === '') { + $this->importDevName = 'device'.$this->trackIndex; + } + $devid = $this->getOrCreateDeviceFromDB($this->importUserId, $this->importDevName); + $this->addPointsToDB($devid, $this->currentPointList); + unset($this->currentPointList); + $this->currentPointList = []; + } + $this->pointIndex++; + } + } + + private function gpxDataElement($parser, $data) { + $d = trim($data); + if (!empty($d)) { + if ($this->currentXmlTag === 'ELE') { + $this->currentPoint['altitude'] = (isset($this->currentPoint['altitude'])) ? $this->currentPoint['altitude'].$d : $d; + } elseif ($this->currentXmlTag === 'BATTERYLEVEL') { + $this->currentPoint['battery'] = (isset($this->currentPoint['battery'])) ? $this->currentPoint['battery'].$d : $d; + } elseif ($this->currentXmlTag === 'ACCURACY') { + $this->currentPoint['accuracy'] = (isset($this->currentPoint['accuracy'])) ? $this->currentPoint['accuracy'].$d : $d; + } elseif ($this->insideTrk and $this->currentXmlTag === 'TIME') { + $this->currentPoint['date'] = (isset($this->currentPoint['date'])) ? $this->currentPoint['date'].$d : $d; + } elseif ($this->insideTrk and $this->currentXmlTag === 'NAME') { + $this->importDevName = $this->importDevName . $d; + } + } + } + + public function importDevicesFromKmz($userId, $file) { + $path = $file->getStorage()->getLocalFile($file->getInternalPath()); + $name = $file->getName(); + $zf = new ZIP($path); + if (count($zf->getFiles()) > 0) { + $zippedFilePath = $zf->getFiles()[0]; + $fstream = $zf->getStream($zippedFilePath, 'r'); + + $nbImported = $this->importDevicesFromKml($userId, $fstream, $name); + } else { + $nbImported = 0; + } + return $nbImported; + } + + public function importDevicesFromKml($userId, $fp, $name) { + $this->trackIndex = 1; + $this->importUserId = $userId; + $this->importFileName = $name; + $xml_parser = xml_parser_create(); + xml_set_object($xml_parser, $this); + xml_set_element_handler($xml_parser, 'kmlStartElement', 'kmlEndElement'); + xml_set_character_data_handler($xml_parser, 'kmlDataElement'); + + while ($data = fread($fp, 4096000)) { + if (!xml_parse($xml_parser, $data, feof($fp))) { + $this->logger->error( + 'Exception in '.$name.' parsing at line '. + xml_get_current_line_number($xml_parser).' : '. + xml_error_string(xml_get_error_code($xml_parser)), + ['app' => $this->appName] + ); + return 0; + } + } + fclose($fp); + xml_parser_free($xml_parser); + return ($this->trackIndex - 1); + } + + private function kmlStartElement($parser, $name, $attrs) { + $this->currentXmlTag = $name; + if ($name === 'GX:TRACK') { + if (isset($attrs['ID'])) { + $this->importDevName = $attrs['ID']; + } else { + $this->importDevName = $this->importFileName.' '.$this->trackIndex; + } + $this->pointIndex = 1; + $this->currentPointList = []; + } elseif ($name === 'WHEN') { + $this->currentPoint = []; + } + //var_dump($attrs); + } + + private function kmlEndElement($parser, $name) { + if ($name === 'GX:TRACK') { + // log last track points + if (count($this->currentPointList) > 0) { + $devid = $this->getOrCreateDeviceFromDB($this->importUserId, $this->importDevName); + $this->addPointsToDB($devid, $this->currentPointList); + } + $this->trackIndex++; + unset($this->currentPointList); + } elseif ($name === 'GX:COORD') { + // convert date + if (isset($this->currentPoint['date'])) { + $time = new \DateTime($this->currentPoint['date']); + $timestamp = $time->getTimestamp(); + $this->currentPoint['date'] = $timestamp; + } + // get latlng + if (isset($this->currentPoint['coords'])) { + $spl = explode(' ', $this->currentPoint['coords']); + if (count($spl) > 1) { + $this->currentPoint['lat'] = floatval($spl[1]); + $this->currentPoint['lng'] = floatval($spl[0]); + if (count($spl) > 2) { + $this->currentPoint['altitude'] = floatval($spl[2]); + } + } + } + // store track point + array_push($this->currentPointList, $this->currentPoint); + // if we have enough points, we log them and clean the points array + if (count($this->currentPointList) >= 500) { + $devid = $this->getOrCreateDeviceFromDB($this->importUserId, $this->importDevName); + $this->addPointsToDB($devid, $this->currentPointList); + unset($this->currentPointList); + $this->currentPointList = []; + } + $this->pointIndex++; + } + } + + private function kmlDataElement($parser, $data) { + $d = trim($data); + if (!empty($d)) { + if ($this->currentXmlTag === 'WHEN') { + $this->currentPoint['date'] = (isset($this->currentPoint['date'])) ? $this->currentPoint['date'].$d : $d; + } elseif ($this->currentXmlTag === 'GX:COORD') { + $this->currentPoint['coords'] = (isset($this->currentPoint['coords'])) ? $this->currentPoint['coords'].$d : $d; + } + } + } + + private function endswith($string, $test) { + $strlen = strlen($string); + $testlen = strlen($test); + if ($testlen > $strlen) { + return false; + } + return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0; + } /** * @param $folder @@ -803,17 +791,17 @@ private function endswith($string, $test) { * @return mixed * @throws NotFoundException */ - public function getSharedDevicesFromFolder($folder, bool $isCreatable=true) { + public function getSharedDevicesFromFolder($folder, bool $isCreatable = true) { try { - $file=$folder->get(".device_shares.json"); + $file = $folder->get('.device_shares.json'); } catch (NotFoundException $e) { if ($isCreatable) { - $file=$folder->newFile(".device_shares.json", $content = '[]'); + $file = $folder->newFile('.device_shares.json', $content = '[]'); } else { throw new NotFoundException(); } } - return json_decode($file->getContent(),true); + return json_decode($file->getContent(), true); } } diff --git a/lib/Service/FavoritesService.php b/lib/Service/FavoritesService.php index a2534482a..f57c65c30 100644 --- a/lib/Service/FavoritesService.php +++ b/lib/Service/FavoritesService.php @@ -18,76 +18,76 @@ use OC\Archive\ZIP; use OC\Security\SecureRandom; use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IDBConnection; use OCP\IL10N; use OCP\ILogger; -use OCP\IDBConnection; class FavoritesService { - private $l10n; - private $logger; - private $qb; - private $dbconnection; - private $secureRandom; - - private $currentFavorite; - private $currentFavoritesList; - private $insideWpt; - private $nbImported; - private $importUserId; - private $kmlInsidePlacemark; - private $kmlCurrentCategory; - - public function __construct(ILogger $logger, IL10N $l10n, SecureRandom $secureRandom, - IDBConnection $dbconnection) { - $this->l10n = $l10n; - $this->logger = $logger; - $this->secureRandom = $secureRandom; - $this->dbconnection = $dbconnection; - $this->qb = $dbconnection->getQueryBuilder(); - } - - private function db_quote_escape_string($str) { - return $this->dbconnection->quote($str); - } - - /** - * @param string $userId - * @param int $pruneBefore - * @param string|null $filterCategory - * @return array with favorites - */ - public function getFavoritesFromDB($userId, $pruneBefore = 0, $filterCategory = null, $isDeletable=true, $isUpdateable=true, $isShareable=true) { - $favorites = []; - $qb = $this->qb; - $qb->select('id', 'name', 'date_created', 'date_modified', 'lat', 'lng', 'category', 'comment', 'extensions') - ->from('maps_favorites', 'f') - ->where( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - if (intval($pruneBefore) > 0) { - $qb->andWhere( - $qb->expr()->gt('date_modified', $qb->createNamedParameter($pruneBefore, IQueryBuilder::PARAM_INT)) - ); - } - if ($filterCategory !== null) { - $qb->andWhere( - $qb->expr()->eq('category', $qb->createNamedParameter($filterCategory, IQueryBuilder::PARAM_STR)) - ); - } - $req = $qb->execute(); - - while ($row = $req->fetch()) { - $id = intval($row['id']); - $name = $row['name']; - $date_modified = intval($row['date_modified']); - $date_created = intval($row['date_created']); - $lat = floatval($row['lat']); - $lng = floatval($row['lng']); - $category = $row['category']; - $comment = $row['comment']; - $extensions = $row['extensions']; - $favorites[] = [ + private $l10n; + private $logger; + private $qb; + private $dbconnection; + private $secureRandom; + + private $currentFavorite; + private $currentFavoritesList; + private $insideWpt; + private $nbImported; + private $importUserId; + private $kmlInsidePlacemark; + private $kmlCurrentCategory; + + public function __construct(ILogger $logger, IL10N $l10n, SecureRandom $secureRandom, + IDBConnection $dbconnection) { + $this->l10n = $l10n; + $this->logger = $logger; + $this->secureRandom = $secureRandom; + $this->dbconnection = $dbconnection; + $this->qb = $dbconnection->getQueryBuilder(); + } + + private function db_quote_escape_string($str) { + return $this->dbconnection->quote($str); + } + + /** + * @param string $userId + * @param int $pruneBefore + * @param string|null $filterCategory + * @return array with favorites + */ + public function getFavoritesFromDB($userId, $pruneBefore = 0, $filterCategory = null, $isDeletable = true, $isUpdateable = true, $isShareable = true) { + $favorites = []; + $qb = $this->qb; + $qb->select('id', 'name', 'date_created', 'date_modified', 'lat', 'lng', 'category', 'comment', 'extensions') + ->from('maps_favorites', 'f') + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + if (intval($pruneBefore) > 0) { + $qb->andWhere( + $qb->expr()->gt('date_modified', $qb->createNamedParameter($pruneBefore, IQueryBuilder::PARAM_INT)) + ); + } + if ($filterCategory !== null) { + $qb->andWhere( + $qb->expr()->eq('category', $qb->createNamedParameter($filterCategory, IQueryBuilder::PARAM_STR)) + ); + } + $req = $qb->execute(); + + while ($row = $req->fetch()) { + $id = intval($row['id']); + $name = $row['name']; + $date_modified = intval($row['date_modified']); + $date_created = intval($row['date_created']); + $lat = floatval($row['lat']); + $lng = floatval($row['lng']); + $category = $row['category']; + $comment = $row['comment']; + $extensions = $row['extensions']; + $favorites[] = [ 'id' => $id, 'name' => $name, 'date_modified' => $date_modified, @@ -102,289 +102,287 @@ public function getFavoritesFromDB($userId, $pruneBefore = 0, $filterCategory = 'isUpdateable' => $isUpdateable, 'isShareable' => $isShareable, ]; - } - $req->closeCursor(); - $qb = $qb->resetQueryParts(); - return $favorites; - } - - public function getFavoriteFromDB($id, $userId = null, $category = null, $isDeletable=true, $isUpdateable=true, $isShareable=true) { - $favorite = null; - $qb = $this->qb; - $qb->select('id', 'name', 'date_modified', 'date_created', 'lat', 'lng', 'category', 'comment', 'extensions') - ->from('maps_favorites', 'f') - ->where( - $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) - ); - if ($userId !== null) { - $qb->andWhere( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - } - if ($category !== null) { - $qb->andWhere( - $qb->expr()->eq('category', $qb->createNamedParameter($category, IQueryBuilder::PARAM_STR)) - ); - } - $req = $qb->execute(); - - while ($row = $req->fetch()) { - $id = intval($row['id']); - $name = $row['name']; - $date_modified = intval($row['date_modified']); - $date_created = intval($row['date_created']); - $lat = floatval($row['lat']); - $lng = floatval($row['lng']); - $category = $row['category']; - $comment = $row['comment']; - $extensions = $row['extensions']; - $favorite = [ - 'id' => $id, - 'name' => $name, - 'date_modified' => $date_modified, - 'date_created' => $date_created, - 'lat' => $lat, - 'lng' => $lng, - 'category' => $category, - 'comment' => $comment, - 'extensions' => $extensions, + } + $req->closeCursor(); + $qb = $qb->resetQueryParts(); + return $favorites; + } + + public function getFavoriteFromDB($id, $userId = null, $category = null, $isDeletable = true, $isUpdateable = true, $isShareable = true) { + $favorite = null; + $qb = $this->qb; + $qb->select('id', 'name', 'date_modified', 'date_created', 'lat', 'lng', 'category', 'comment', 'extensions') + ->from('maps_favorites', 'f') + ->where( + $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) + ); + if ($userId !== null) { + $qb->andWhere( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + } + if ($category !== null) { + $qb->andWhere( + $qb->expr()->eq('category', $qb->createNamedParameter($category, IQueryBuilder::PARAM_STR)) + ); + } + $req = $qb->execute(); + + while ($row = $req->fetch()) { + $id = intval($row['id']); + $name = $row['name']; + $date_modified = intval($row['date_modified']); + $date_created = intval($row['date_created']); + $lat = floatval($row['lat']); + $lng = floatval($row['lng']); + $category = $row['category']; + $comment = $row['comment']; + $extensions = $row['extensions']; + $favorite = [ + 'id' => $id, + 'name' => $name, + 'date_modified' => $date_modified, + 'date_created' => $date_created, + 'lat' => $lat, + 'lng' => $lng, + 'category' => $category, + 'comment' => $comment, + 'extensions' => $extensions, 'isDeletable' => $isDeletable, //Saving maps information in the file 'isUpdateable' => $isUpdateable, 'isShareable' => $isShareable, - ]; - break; - } - $req->closeCursor(); - $qb = $qb->resetQueryParts(); - return $favorite; - } - - public function addFavoriteToDB($userId, $name, $lat, $lng, $category, $comment, $extensions) { - $nowTimeStamp = (new \DateTime())->getTimestamp(); - $qb = $this->qb; - $qb->insert('maps_favorites') - ->values([ - 'user_id' => $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR), - 'name' => $qb->createNamedParameter($name, IQueryBuilder::PARAM_STR), - 'date_created' => $qb->createNamedParameter($nowTimeStamp, IQueryBuilder::PARAM_INT), - 'date_modified' => $qb->createNamedParameter($nowTimeStamp, IQueryBuilder::PARAM_INT), - 'lat' => $qb->createNamedParameter($lat, IQueryBuilder::PARAM_STR), - 'lng' => $qb->createNamedParameter($lng, IQueryBuilder::PARAM_STR), - 'category' => $qb->createNamedParameter($category, IQueryBuilder::PARAM_STR), - 'comment' => $qb->createNamedParameter($comment, IQueryBuilder::PARAM_STR), - 'extensions' => $qb->createNamedParameter($extensions, IQueryBuilder::PARAM_STR) - ]); - $req = $qb->execute(); - $favoriteId = $qb->getLastInsertId(); - $qb = $qb->resetQueryParts(); - return $favoriteId; - } - - public function addMultipleFavoritesToDB($userId, $favoriteList) { - $nowTimeStamp = (new \DateTime())->getTimestamp(); - - $values = []; - foreach ($favoriteList as $fav) { - if ( - !isset($fav['lat']) or !is_numeric($fav['lat']) or - !isset($fav['lng']) or !is_numeric($fav['lng']) - ) { - continue; - } - else { - $lat = floatval($fav['lat']); - $lng = floatval($fav['lng']); - } - $value = '(' . - $this->db_quote_escape_string($userId) . ', ' . - ((!isset($fav['name']) or !$fav['name']) ? 'NULL' : $this->db_quote_escape_string($fav['name'])) . ', ' . - ((!isset($fav['date_created']) or !is_numeric($fav['date_created'])) ? $this->db_quote_escape_string($nowTimeStamp) : $this->db_quote_escape_string($fav['date_created'])) . ', ' . - $this->db_quote_escape_string($nowTimeStamp) . ', ' . - $this->db_quote_escape_string($lat) . ', ' . - $this->db_quote_escape_string($lng) . ', ' . - ((!isset($fav['category']) or !$fav['category']) ? 'NULL' : $this->db_quote_escape_string($fav['category'])) . ', ' . - ((!isset($fav['comment']) or !$fav['comment']) ? 'NULL' : $this->db_quote_escape_string($fav['comment'])) . ', ' . - ((!isset($fav['extensions']) or !$fav['extensions']) ? 'NULL' : $this->db_quote_escape_string($fav['extensions'])) . ')'; - array_push($values, $value); - } - $valuesStr = implode(', ', $values); - $sql = ' + ]; + break; + } + $req->closeCursor(); + $qb = $qb->resetQueryParts(); + return $favorite; + } + + public function addFavoriteToDB($userId, $name, $lat, $lng, $category, $comment, $extensions) { + $nowTimeStamp = (new \DateTime())->getTimestamp(); + $qb = $this->qb; + $qb->insert('maps_favorites') + ->values([ + 'user_id' => $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR), + 'name' => $qb->createNamedParameter($name, IQueryBuilder::PARAM_STR), + 'date_created' => $qb->createNamedParameter($nowTimeStamp, IQueryBuilder::PARAM_INT), + 'date_modified' => $qb->createNamedParameter($nowTimeStamp, IQueryBuilder::PARAM_INT), + 'lat' => $qb->createNamedParameter($lat, IQueryBuilder::PARAM_STR), + 'lng' => $qb->createNamedParameter($lng, IQueryBuilder::PARAM_STR), + 'category' => $qb->createNamedParameter($category, IQueryBuilder::PARAM_STR), + 'comment' => $qb->createNamedParameter($comment, IQueryBuilder::PARAM_STR), + 'extensions' => $qb->createNamedParameter($extensions, IQueryBuilder::PARAM_STR) + ]); + $req = $qb->execute(); + $favoriteId = $qb->getLastInsertId(); + $qb = $qb->resetQueryParts(); + return $favoriteId; + } + + public function addMultipleFavoritesToDB($userId, $favoriteList) { + $nowTimeStamp = (new \DateTime())->getTimestamp(); + + $values = []; + foreach ($favoriteList as $fav) { + if ( + !isset($fav['lat']) or !is_numeric($fav['lat']) or + !isset($fav['lng']) or !is_numeric($fav['lng']) + ) { + continue; + } else { + $lat = floatval($fav['lat']); + $lng = floatval($fav['lng']); + } + $value = '(' . + $this->db_quote_escape_string($userId) . ', ' . + ((!isset($fav['name']) or !$fav['name']) ? 'NULL' : $this->db_quote_escape_string($fav['name'])) . ', ' . + ((!isset($fav['date_created']) or !is_numeric($fav['date_created'])) ? $this->db_quote_escape_string($nowTimeStamp) : $this->db_quote_escape_string($fav['date_created'])) . ', ' . + $this->db_quote_escape_string($nowTimeStamp) . ', ' . + $this->db_quote_escape_string($lat) . ', ' . + $this->db_quote_escape_string($lng) . ', ' . + ((!isset($fav['category']) or !$fav['category']) ? 'NULL' : $this->db_quote_escape_string($fav['category'])) . ', ' . + ((!isset($fav['comment']) or !$fav['comment']) ? 'NULL' : $this->db_quote_escape_string($fav['comment'])) . ', ' . + ((!isset($fav['extensions']) or !$fav['extensions']) ? 'NULL' : $this->db_quote_escape_string($fav['extensions'])) . ')'; + array_push($values, $value); + } + $valuesStr = implode(', ', $values); + $sql = ' INSERT INTO *PREFIX*maps_favorites (user_id, name, date_created, date_modified, lat, lng, category, comment, extensions) VALUES ' . $valuesStr . ' ;'; - $req = $this->dbconnection->prepare($sql); - $req->execute(); - $req->closeCursor(); - } - - public function renameCategoryInDB($userId, $cat, $newName) { - $qb = $this->qb; - $qb->update('maps_favorites'); - $qb->set('category', $qb->createNamedParameter($newName, IQueryBuilder::PARAM_STR)); - $qb->where( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - $qb->andWhere( - $qb->expr()->eq('category', $qb->createNamedParameter($cat, IQueryBuilder::PARAM_STR)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - - public function editFavoriteInDB($id, $name, $lat, $lng, $category, $comment, $extensions) { - $nowTimeStamp = (new \DateTime())->getTimestamp(); - $qb = $this->qb; - $qb->update('maps_favorites'); - $qb->set('date_modified', $qb->createNamedParameter($nowTimeStamp, IQueryBuilder::PARAM_INT)); - if ($name !== null) { - $qb->set('name', $qb->createNamedParameter($name, IQueryBuilder::PARAM_STR)); - } - if ($lat !== null) { - $qb->set('lat', $qb->createNamedParameter($lat, IQueryBuilder::PARAM_STR)); - } - if ($lng !== null) { - $qb->set('lng', $qb->createNamedParameter($lng, IQueryBuilder::PARAM_STR)); - } - if ($category !== null) { - $qb->set('category', $qb->createNamedParameter($category, IQueryBuilder::PARAM_STR)); - } - if ($comment !== null) { - $qb->set('comment', $qb->createNamedParameter($comment, IQueryBuilder::PARAM_STR)); - } - if ($extensions !== null) { - $qb->set('extensions', $qb->createNamedParameter($extensions, IQueryBuilder::PARAM_STR)); - } - $qb->where( - $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - - public function deleteFavoriteFromDB($id) { - $qb = $this->qb; - $qb->delete('maps_favorites') - ->where( - $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - - public function deleteFavoritesFromDB($ids, $userId) { - $qb = $this->qb; - $qb->delete('maps_favorites') - ->where( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - if (count($ids) > 0) { - $or = $qb->expr()->orx(); - foreach ($ids as $id) { - $or->add($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT))); - } - $qb->andWhere($or); - } - else { - return; - } - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - - public function countFavorites($userId, $categoryList, $begin, $end) { - if ($categoryList === null or - (is_array($categoryList) and count($categoryList) === 0) - ) { - return 0; - } - $qb = $this->qb; - $qb->select($qb->createFunction('COUNT(*) AS co')) - ->from('maps_favorites', 'f') - ->where( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - if ($begin !== null) { - $qb->andWhere( - $qb->expr()->gt('date_created', $qb->createNamedParameter($begin, IQueryBuilder::PARAM_INT)) - ); - } - if ($end !== null) { - $qb->andWhere( - $qb->expr()->lt('date_created', $qb->createNamedParameter($end, IQueryBuilder::PARAM_INT)) - ); - } - // apply category restrictions if it's a non-empty array - if (!is_string($categoryList) and - is_array($categoryList) and - count($categoryList) > 0 - ) { - $or = $qb->expr()->orx(); - foreach ($categoryList as $cat) { - $or->add($qb->expr()->eq('category', $qb->createNamedParameter($cat, IQueryBuilder::PARAM_STR))); - } - $qb->andWhere($or); - } - $nbFavorites = 0; - $req = $qb->execute(); - while ($row = $req->fetch()) { - $nbFavorites = intval($row['co']); - break; - } - $req->closeCursor(); - $qb = $qb->resetQueryParts(); - - return $nbFavorites; - } + $req = $this->dbconnection->prepare($sql); + $req->execute(); + $req->closeCursor(); + } + + public function renameCategoryInDB($userId, $cat, $newName) { + $qb = $this->qb; + $qb->update('maps_favorites'); + $qb->set('category', $qb->createNamedParameter($newName, IQueryBuilder::PARAM_STR)); + $qb->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + $qb->andWhere( + $qb->expr()->eq('category', $qb->createNamedParameter($cat, IQueryBuilder::PARAM_STR)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + + public function editFavoriteInDB($id, $name, $lat, $lng, $category, $comment, $extensions) { + $nowTimeStamp = (new \DateTime())->getTimestamp(); + $qb = $this->qb; + $qb->update('maps_favorites'); + $qb->set('date_modified', $qb->createNamedParameter($nowTimeStamp, IQueryBuilder::PARAM_INT)); + if ($name !== null) { + $qb->set('name', $qb->createNamedParameter($name, IQueryBuilder::PARAM_STR)); + } + if ($lat !== null) { + $qb->set('lat', $qb->createNamedParameter($lat, IQueryBuilder::PARAM_STR)); + } + if ($lng !== null) { + $qb->set('lng', $qb->createNamedParameter($lng, IQueryBuilder::PARAM_STR)); + } + if ($category !== null) { + $qb->set('category', $qb->createNamedParameter($category, IQueryBuilder::PARAM_STR)); + } + if ($comment !== null) { + $qb->set('comment', $qb->createNamedParameter($comment, IQueryBuilder::PARAM_STR)); + } + if ($extensions !== null) { + $qb->set('extensions', $qb->createNamedParameter($extensions, IQueryBuilder::PARAM_STR)); + } + $qb->where( + $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + + public function deleteFavoriteFromDB($id) { + $qb = $this->qb; + $qb->delete('maps_favorites') + ->where( + $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + + public function deleteFavoritesFromDB($ids, $userId) { + $qb = $this->qb; + $qb->delete('maps_favorites') + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + if (count($ids) > 0) { + $or = $qb->expr()->orx(); + foreach ($ids as $id) { + $or->add($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT))); + } + $qb->andWhere($or); + } else { + return; + } + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + + public function countFavorites($userId, $categoryList, $begin, $end) { + if ($categoryList === null or + (is_array($categoryList) and count($categoryList) === 0) + ) { + return 0; + } + $qb = $this->qb; + $qb->select($qb->createFunction('COUNT(*) AS co')) + ->from('maps_favorites', 'f') + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + if ($begin !== null) { + $qb->andWhere( + $qb->expr()->gt('date_created', $qb->createNamedParameter($begin, IQueryBuilder::PARAM_INT)) + ); + } + if ($end !== null) { + $qb->andWhere( + $qb->expr()->lt('date_created', $qb->createNamedParameter($end, IQueryBuilder::PARAM_INT)) + ); + } + // apply category restrictions if it's a non-empty array + if (!is_string($categoryList) and + is_array($categoryList) and + count($categoryList) > 0 + ) { + $or = $qb->expr()->orx(); + foreach ($categoryList as $cat) { + $or->add($qb->expr()->eq('category', $qb->createNamedParameter($cat, IQueryBuilder::PARAM_STR))); + } + $qb->andWhere($or); + } + $nbFavorites = 0; + $req = $qb->execute(); + while ($row = $req->fetch()) { + $nbFavorites = intval($row['co']); + break; + } + $req->closeCursor(); + $qb = $qb->resetQueryParts(); + + return $nbFavorites; + } /** * @param $file * @return array * @throws \Exception */ - public function getFavoritesFromJSON($file) { - $favorites = []; + public function getFavoritesFromJSON($file) { + $favorites = []; - // Decode file content from JSON - $data = json_decode($file->getContent(), true, 512); + // Decode file content from JSON + $data = json_decode($file->getContent(), true, 512); - $id = 0; - // Loop over all favorite entries - foreach($data['features'] as $value) { - $currentFavorite = [ - "id"=>$id, + $id = 0; + // Loop over all favorite entries + foreach ($data['features'] as $value) { + $currentFavorite = [ + 'id' => $id, 'isDeletable' => $file->isUpdateable(), //Saving maps information in the file 'isUpdateable' => $file->isUpdateable(), 'isShareable' => false, 'extensions' => [], - ]; + ]; - // Read geometry + // Read geometry $currentFavorite['lng'] = floatval($value['geometry']['coordinates'][0]); $currentFavorite['lat'] = floatval($value['geometry']['coordinates'][1]); foreach ($value['properties'] as $key => $v) { - if($key === 'Title') { + if ($key === 'Title') { $currentFavorite['name'] = $value['properties']['Title']; - } else if($key === 'Published') { - if (!is_numeric($value['properties']['Published'])){ + } elseif ($key === 'Published') { + if (!is_numeric($value['properties']['Published'])) { $time = new \DateTime($value['properties']['Published']); $time = $time->getTimestamp(); } else { $time = $value['properties']['Published']; } $currentFavorite['date_created'] = $time; - } else if($key === 'Updated') { - if (!is_numeric($value['properties']['Updated'])){ + } elseif ($key === 'Updated') { + if (!is_numeric($value['properties']['Updated'])) { $time = new \DateTime($value['properties']['Updated']); $time = $time->getTimestamp(); } else { $time = $value['properties']['Updated']; } $currentFavorite['date_modified'] = $time; - } else if ($key === 'Category') { + } elseif ($key === 'Category') { $currentFavorite['category'] = $v; - } else if ($key === 'Comment') { + } elseif ($key === 'Comment') { $currentFavorite['comment'] = $v; } else { $currentFavorite[$key] = $v; @@ -393,75 +391,75 @@ public function getFavoritesFromJSON($file) { } - if(!array_key_exists('category', $currentFavorite)) { + if (!array_key_exists('category', $currentFavorite)) { $currentFavorite['category'] = $this->l10n->t('Personal'); } - if(!array_key_exists('comment', $currentFavorite)) { + if (!array_key_exists('comment', $currentFavorite)) { $currentFavorite['comment'] = ''; } - if( + if ( array_key_exists('Location', $value['properties']) && array_key_exists('Address', $value['properties']['Location']) ) { $currentFavorite['comment'] = $currentFavorite['comment']."\n".$value['properties']['Location']['Address']; } - // Store this favorite - $favorites[] = $currentFavorite; - $id++; - } + // Store this favorite + $favorites[] = $currentFavorite; + $id++; + } - return $favorites; - } + return $favorites; + } - public function getFavoriteFromJSON($file, $id) { + public function getFavoriteFromJSON($file, $id) { $favorites = $this->getFavoritesFromJSON($file); if (array_key_exists($id, $favorites)) { return $favorites[$id]; } else { return null; } - } + } private function addFavoriteToJSONData($data, $name, $lat, $lng, $category, $comment, $extensions, $nowTimeStamp) { $favorite = [ - "type" => "Feature", - "geometry" => [ - "type" => "Point", - "coordinates" => [ + 'type' => 'Feature', + 'geometry' => [ + 'type' => 'Point', + 'coordinates' => [ $lng, $lat ] ], - "properties" => [ - "Title" => $name, - "Category" => $category, - "Published" => $nowTimeStamp, - "Updated" => $nowTimeStamp, - "Comment" => $comment, + 'properties' => [ + 'Title' => $name, + 'Category' => $category, + 'Published' => $nowTimeStamp, + 'Updated' => $nowTimeStamp, + 'Comment' => $comment, ] ]; - if(is_array($extensions)){ + if (is_array($extensions)) { foreach ($extensions as $key => $value) { - $favorite["properties"][$key] = $value; + $favorite['properties'][$key] = $value; } } $id = array_push($data['features'], $favorite) - 1; return [ - "id" => $id, - "data" =>$data, + 'id' => $id, + 'data' => $data, ]; } - public function addFavoriteToJSON($file, $name, $lat, $lng, $category, $comment, $extensions) { - $nowTimeStamp = (new \DateTime())->getTimestamp(); - $data = json_decode($file->getContent(), true, 512); + public function addFavoriteToJSON($file, $name, $lat, $lng, $category, $comment, $extensions) { + $nowTimeStamp = (new \DateTime())->getTimestamp(); + $data = json_decode($file->getContent(), true, 512); $tmp = $this->addFavoriteToJSONData($data, $name, $lat, $lng, $category, $comment, $extensions, $nowTimeStamp); - $file->putContent(json_encode($tmp["data"],JSON_PRETTY_PRINT)); - return $tmp["id"]; - } + $file->putContent(json_encode($tmp['data'], JSON_PRETTY_PRINT)); + return $tmp['id']; + } public function addFavoritesToJSON($file, $favorites) { $nowTimeStamp = (new \DateTime())->getTimestamp(); @@ -469,497 +467,484 @@ public function addFavoritesToJSON($file, $favorites) { $ids = []; foreach ($favorites as $favorite) { $tmp = $this->addFavoriteToJSONData($data, $favorite['name'], $favorite['lat'], $favorite['lng'], $favorite['category'], $favorite['comment'], $favorite['extensions'], $nowTimeStamp); - $ids[] = $tmp["id"]; - $data = $tmp["data"]; + $ids[] = $tmp['id']; + $data = $tmp['data']; } - $file->putContent(json_encode($data,JSON_PRETTY_PRINT)); + $file->putContent(json_encode($data, JSON_PRETTY_PRINT)); return $ids; } - public function renameCategoryInJSON($file, $cat, $newName) { - $nowTimeStamp = (new \DateTime())->getTimestamp(); - $data = json_decode($file->getContent(), true, 512); - $this->logger->debug($cat); - foreach ($data['features'] as $key => $value) { - if (!array_key_exists('Category', $value['properties']) ){ - $value['properties']['Category'] = $this->l10n->t('Personal'); - $data['features'][$key]['properties']['Category'] = $this->l10n->t('Personal'); - } - if (array_key_exists('Category', $value['properties']) && $value['properties']['Category'] == $cat) { - $data['features'][$key]['properties']['Category'] = $newName; - $data['features'][$key]['properties']['Updated'] = $nowTimeStamp; - } - } - $file->putContent(json_encode($data,JSON_PRETTY_PRINT)); - } - - public function editFavoriteInJSON($file, $id, $name, $lat, $lng, $category, $comment, $extensions) { - $nowTimeStamp = (new \DateTime())->getTimestamp(); - $data = json_decode($file->getContent(), true, 512); - $createdTimeStamp = $data['features'][$id]['properties']['Published']; - $favorite = [ - "type" => "Feature", - "geometry" => [ - "type" => "Point", - "coordinates" => [ - $lng ?? $data['features'][$id]["geometry"]["coordinates"][0], - $lat ?? $data['features'][$id]["geometry"]["coordinates"][1] - ] - ], - "properties" => [ - "Title" => $name ?? $data['features'][$id]["properties"]["Title"], - "Category" => $category ?? $data['features'][$id]["properties"]["Category"], - "Published" => $createdTimeStamp, - "Updated" => $nowTimeStamp, - "Comment" => $comment ?? $data['features'][$id]["properties"]["Comment"], - ] - ]; - if (is_array($extensions)) { - foreach ($extensions as $key => $value) { - $favorite["properties"][$key] = $value; - } - } - - $data['features'][$id] = $favorite; - - $file->putContent(json_encode($data,JSON_PRETTY_PRINT)); - } - - public function deleteFavoriteFromJSON($file, $id): int { - $data = json_decode($file->getContent(), true, 512); + public function renameCategoryInJSON($file, $cat, $newName) { + $nowTimeStamp = (new \DateTime())->getTimestamp(); + $data = json_decode($file->getContent(), true, 512); + $this->logger->debug($cat); + foreach ($data['features'] as $key => $value) { + if (!array_key_exists('Category', $value['properties'])) { + $value['properties']['Category'] = $this->l10n->t('Personal'); + $data['features'][$key]['properties']['Category'] = $this->l10n->t('Personal'); + } + if (array_key_exists('Category', $value['properties']) && $value['properties']['Category'] == $cat) { + $data['features'][$key]['properties']['Category'] = $newName; + $data['features'][$key]['properties']['Updated'] = $nowTimeStamp; + } + } + $file->putContent(json_encode($data, JSON_PRETTY_PRINT)); + } + + public function editFavoriteInJSON($file, $id, $name, $lat, $lng, $category, $comment, $extensions) { + $nowTimeStamp = (new \DateTime())->getTimestamp(); + $data = json_decode($file->getContent(), true, 512); + $createdTimeStamp = $data['features'][$id]['properties']['Published']; + $favorite = [ + 'type' => 'Feature', + 'geometry' => [ + 'type' => 'Point', + 'coordinates' => [ + $lng ?? $data['features'][$id]['geometry']['coordinates'][0], + $lat ?? $data['features'][$id]['geometry']['coordinates'][1] + ] + ], + 'properties' => [ + 'Title' => $name ?? $data['features'][$id]['properties']['Title'], + 'Category' => $category ?? $data['features'][$id]['properties']['Category'], + 'Published' => $createdTimeStamp, + 'Updated' => $nowTimeStamp, + 'Comment' => $comment ?? $data['features'][$id]['properties']['Comment'], + ] + ]; + if (is_array($extensions)) { + foreach ($extensions as $key => $value) { + $favorite['properties'][$key] = $value; + } + } + + $data['features'][$id] = $favorite; + + $file->putContent(json_encode($data, JSON_PRETTY_PRINT)); + } + + public function deleteFavoriteFromJSON($file, $id): int { + $data = json_decode($file->getContent(), true, 512); $countBefore = count($data['features']); - array_splice($data['features'], $id, 1); - $file->putContent(json_encode($data,JSON_PRETTY_PRINT)); + array_splice($data['features'], $id, 1); + $file->putContent(json_encode($data, JSON_PRETTY_PRINT)); return $countBefore - count($data['features']); - } + } - public function deleteFavoritesFromJSON($file, $ids) { - $data = json_decode($file->getContent(), true, 512); - foreach ($ids as $id) { - array_splice($data['features'], $id, 1); - } - $file->putContent(json_encode($data,JSON_PRETTY_PRINT)); - } + public function deleteFavoritesFromJSON($file, $ids) { + $data = json_decode($file->getContent(), true, 512); + foreach ($ids as $id) { + array_splice($data['features'], $id, 1); + } + $file->putContent(json_encode($data, JSON_PRETTY_PRINT)); + } - public function exportFavorites($userId, $fileHandler, $categoryList, $begin, $end, $appVersion) { - $qb = $this->qb; - $nbFavorites = $this->countFavorites($userId, $categoryList, $begin, $end); + public function exportFavorites($userId, $fileHandler, $categoryList, $begin, $end, $appVersion) { + $qb = $this->qb; + $nbFavorites = $this->countFavorites($userId, $categoryList, $begin, $end); - $gpxHeader = ' + $gpxHeader = ' favourites '; - fwrite($fileHandler, $gpxHeader . "\n"); - - $chunkSize = 10000; - $favIndex = 0; - - while ($favIndex < $nbFavorites) { - $gpxText = ''; - - $qb->select('id', 'name', 'date_created', 'date_modified', 'lat', 'lng', 'category', 'comment', 'extensions') - ->from('maps_favorites', 'f') - ->where( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - if ($begin !== null) { - $qb->andWhere( - $qb->expr()->gte('date_created', $qb->createNamedParameter($begin, IQueryBuilder::PARAM_INT)) - ); - } - if ($end !== null) { - $qb->andWhere( - $qb->expr()->lte('date_created', $qb->createNamedParameter($end, IQueryBuilder::PARAM_INT)) - ); - } - // apply category restrictions if it's a non-empty array - if (!is_string($categoryList) and - is_array($categoryList) and - count($categoryList) > 0 - ) { - $or = $qb->expr()->orx(); - foreach ($categoryList as $cat) { - $or->add($qb->expr()->eq('category', $qb->createNamedParameter($cat, IQueryBuilder::PARAM_STR))); - } - $qb->andWhere($or); - } - $qb->orderBy('date_created', 'ASC') - ->setMaxResults($chunkSize) - ->setFirstResult($favIndex); - $req = $qb->execute(); - - while ($row = $req->fetch()) { - $name = str_replace('&', '&', $row['name']); - $epoch = $row['date_created']; - $date = ''; - if (is_numeric($epoch)) { - $epoch = intval($epoch); - $dt = new \DateTime("@$epoch"); - $date = $dt->format('Y-m-d\TH:i:s\Z'); - } - $lat = $row['lat']; - $lng = $row['lng']; - $category = str_replace('&', '&', $row['category']); - $comment = str_replace('&', '&', $row['comment']); - $extensions = str_replace('&', '&', $row['extensions']); - - $gpxExtension = ''; - $gpxText .= ' ' . "\n"; - $gpxText .= ' ' . $name . '' . "\n"; - $gpxText .= ' ' . "\n"; - if ($category !== null && strlen($category) > 0) { - $gpxText .= ' ' . $category . '' . "\n"; - } - else { - $gpxText .= ' ' . $this->l10n->t('Personal') . '' . "\n"; - } - if ($comment !== null && strlen($comment) > 0) { - $gpxText .= ' ' . $comment . '' . "\n"; - } - if ($extensions !== null && strlen($extensions) > 0) { - $gpxExtension .= ' ' . $extensions . '' . "\n"; - } - if ($gpxExtension !== '') { - $gpxText .= ' ' . "\n" . $gpxExtension; - $gpxText .= ' ' . "\n"; - } - $gpxText .= ' ' . "\n"; - } - $req->closeCursor(); - $qb = $qb->resetQueryParts(); - // write the chunk ! - fwrite($fileHandler, $gpxText); - $favIndex = $favIndex + $chunkSize; - } - $gpxEnd = '' . "\n"; - fwrite($fileHandler, $gpxEnd); - } - - public function importFavorites($userId, $file) { - $lowerFileName = strtolower($file->getName()); - if ($this->endswith($lowerFileName, '.gpx')) { - return $this->importFavoritesFromGpx($userId, $file); - } - elseif ($this->endswith($lowerFileName, '.kml')) { - $fp = $file->fopen('r'); - $name = $file->getName(); - return $this->importFavoritesFromKml($userId, $fp, $name); - } - elseif ($this->endswith($lowerFileName, '.kmz')) { - return $this->importFavoritesFromKmz($userId, $file); - } - elseif ($this->endswith($lowerFileName, '.json') or $this->endswith($lowerFileName, '.geojson')) { - return $this->importFavoritesFromGeoJSON($userId, $file); - } - } - - public function importFavoritesFromKmz($userId, $file) { - $path = $file->getStorage()->getLocalFile($file->getInternalPath()); - $name = $file->getName(); - $zf = new ZIP($path); - if (count($zf->getFiles()) > 0) { - $zippedFilePath = $zf->getFiles()[0]; - $fstream = $zf->getStream($zippedFilePath, 'r'); - - $result = $this->importFavoritesFromKml($userId, $fstream, $name); - } - else { - $result = [ - 'nbImported' => 0, - 'linesFound' => false - ]; - } - return $result; - } - - public function importFavoritesFromKml($userId, $fp, $name) { - $this->nbImported = 0; - $this->linesFound = false; - $this->currentFavoritesList = []; - $this->importUserId = $userId; - $this->kmlInsidePlacemark = false; - $this->kmlCurrentCategory = ''; - - $xml_parser = xml_parser_create(); - xml_set_object($xml_parser, $this); - xml_set_element_handler($xml_parser, 'kmlStartElement', 'kmlEndElement'); - xml_set_character_data_handler($xml_parser, 'kmlDataElement'); - - // using xml_parse to be able to parse file chunks in case it's too big - while ($data = fread($fp, 4096000)) { - if (!xml_parse($xml_parser, $data, feof($fp))) { - $this->logger->error( - 'Exception in ' . $name . ' parsing at line ' . - xml_get_current_line_number($xml_parser) . ' : ' . - xml_error_string(xml_get_error_code($xml_parser)), - array('app' => 'maps') - ); - return 0; - } - } - fclose($fp); - xml_parser_free($xml_parser); - - return [ - 'nbImported' => $this->nbImported, - 'linesFound' => $this->linesFound - ]; - } - - private function kmlStartElement($parser, $name, $attrs) { - $this->currentXmlTag = $name; - if ($name === 'PLACEMARK') { - $this->currentFavorite = []; - $this->kmlInsidePlacemark = true; - } - if ($name === 'LINESTRING') { - $this->linesFound = true; - } - } - - private function kmlEndElement($parser, $name) { - if ($name === 'KML') { - // create last bunch - if (count($this->currentFavoritesList) > 0) { - $this->addMultipleFavoritesToDB($this->importUserId, $this->currentFavoritesList); - } - unset($this->currentFavoritesList); - } - else if ($name === 'PLACEMARK') { - $this->kmlInsidePlacemark = false; - // store favorite - $this->nbImported++; - $this->currentFavorite['category'] = $this->kmlCurrentCategory; - if (!isset($this->currentFavorite['category']) or $this->currentFavorite['category'] === '') { - $this->currentFavorite['category'] = $this->l10n->t('Personal'); - } - // convert date - if (isset($this->currentFavorite['date_created'])) { - $time = new \DateTime($this->currentFavorite['date_created']); - $timestamp = $time->getTimestamp(); - $this->currentFavorite['date_created'] = $timestamp; - } - if (isset($this->currentFavorite['coordinates'])) { - $spl = explode(',', $this->currentFavorite['coordinates']); - if (count($spl) > 1) { - $this->currentFavorite['lat'] = floatval($spl[1]); - $this->currentFavorite['lng'] = floatval($spl[0]); - } - } - array_push($this->currentFavoritesList, $this->currentFavorite); - // if we have enough favorites, we create them and clean the array - if (count($this->currentFavoritesList) >= 500) { - $this->addMultipleFavoritesToDB($this->importUserId, $this->currentFavoritesList); - unset($this->currentFavoritesList); - $this->currentFavoritesList = []; - } - } - } - - private function kmlDataElement($parser, $data) { - $d = trim($data); - if (!empty($d)) { - if (!$this->kmlInsidePlacemark) { - if ($this->currentXmlTag === 'NAME') { - $this->kmlCurrentCategory = $this->kmlCurrentCategory . $d; - } - } - else { - if ($this->currentXmlTag === 'NAME') { - $this->currentFavorite['name'] = (isset($this->currentFavorite['name'])) ? $this->currentFavorite['name'] . $d : $d; - } - else if ($this->currentXmlTag === 'WHEN') { - $this->currentFavorite['date_created'] = (isset($this->currentFavorite['date_created'])) ? $this->currentFavorite['date_created'] . $d : $d; - } - else if ($this->currentXmlTag === 'COORDINATES') { - $this->currentFavorite['coordinates'] = (isset($this->currentFavorite['coordinates'])) ? $this->currentFavorite['coordinates'] . $d : $d; - } - else if ($this->currentXmlTag === 'DESCRIPTION') { - $this->currentFavorite['comment'] = (isset($this->currentFavorite['comment'])) ? $this->currentFavorite['comment'] . $d : $d; - } - } - } - } - - public function importFavoritesFromGpx($userId, $file) { - $this->nbImported = 0; - $this->linesFound = false; - $this->currentFavoritesList = []; - $this->importUserId = $userId; - $this->insideWpt = false; - - $xml_parser = xml_parser_create(); - xml_set_object($xml_parser, $this); - xml_set_element_handler($xml_parser, 'gpxStartElement', 'gpxEndElement'); - xml_set_character_data_handler($xml_parser, 'gpxDataElement'); - - $fp = $file->fopen('r'); - - // using xml_parse to be able to parse file chunks in case it's too big - while ($data = fread($fp, 4096000)) { - if (!xml_parse($xml_parser, $data, feof($fp))) { - $this->logger->error( - 'Exception in ' . $file->getName() . ' parsing at line ' . - xml_get_current_line_number($xml_parser) . ' : ' . - xml_error_string(xml_get_error_code($xml_parser)), - array('app' => 'maps') - ); - return 0; - } - } - fclose($fp); - xml_parser_free($xml_parser); - - return [ - 'nbImported' => $this->nbImported, - 'linesFound' => $this->linesFound - ]; - } - - private function gpxStartElement($parser, $name, $attrs) { - $this->currentXmlTag = $name; - if ($name === 'WPT') { - $this->insideWpt = true; - $this->currentFavorite = []; - if (isset($attrs['LAT'])) { - $this->currentFavorite['lat'] = floatval($attrs['LAT']); - } - if (isset($attrs['LON'])) { - $this->currentFavorite['lng'] = floatval($attrs['LON']); - } - } - if ($name === 'TRK' or $name === 'RTE') { - $this->linesFound = true; - } - } - - private function gpxEndElement($parser, $name) { - if ($name === 'GPX') { - // create last bunch - if (count($this->currentFavoritesList) > 0) { - $this->addMultipleFavoritesToDB($this->importUserId, $this->currentFavoritesList); - } - unset($this->currentFavoritesList); - } - else if ($name === 'WPT') { - $this->insideWpt = false; - // store favorite - $this->nbImported++; - // convert date - if (isset($this->currentFavorite['date_created'])) { - $time = new \DateTime($this->currentFavorite['date_created']); - $timestamp = $time->getTimestamp(); - $this->currentFavorite['date_created'] = $timestamp; - } - if (!isset($this->currentFavorite['category']) or $this->currentFavorite['category'] === '') { - $this->currentFavorite['category'] = $this->l10n->t('Personal'); - } - array_push($this->currentFavoritesList, $this->currentFavorite); - // if we have enough favorites, we create them and clean the array - if (count($this->currentFavoritesList) >= 500) { - $this->addMultipleFavoritesToDB($this->importUserId, $this->currentFavoritesList); - unset($this->currentFavoritesList); - $this->currentFavoritesList = []; - } - } - } - - private function gpxDataElement($parser, $data) { - $d = trim($data); - if (!empty($d)) { - if ($this->insideWpt and $this->currentXmlTag === 'NAME') { - $this->currentFavorite['name'] = (isset($this->currentFavorite['name'])) ? $this->currentFavorite['name'] . $d : $d; - } - else if ($this->insideWpt and $this->currentXmlTag === 'TIME') { - $this->currentFavorite['date_created'] = (isset($this->currentFavorite['date_created'])) ? $this->currentFavorite['date_created'] . $d : $d; - } - else if ($this->insideWpt and $this->currentXmlTag === 'TYPE') { - $this->currentFavorite['category'] = (isset($this->currentFavorite['category'])) ? $this->currentFavorite['category'] . $d : $d; - } - else if ($this->insideWpt and $this->currentXmlTag === 'DESC') { - $this->currentFavorite['comment'] = (isset($this->currentFavorite['comment'])) ? $this->currentFavorite['comment'] . $d : $d; - } - else if ($this->insideWpt and $this->currentXmlTag === 'MAPS-EXTENSIONS') { - $this->currentFavorite['extensions'] = (isset($this->currentFavorite['extensions'])) ? $this->currentFavorite['extensions'] . $d : $d; - } - } - } - - public function importFavoritesFromGeoJSON($userId, $file) { - $this->nbImported = 0; - $this->linesFound = false; - $this->currentFavoritesList = []; - $this->importUserId = $userId; - - - // Decode file content from JSON - $data = json_decode($file->getContent(), true, 512); - - if($data == null or !isset($data['features'])) { - $this->logger->error( - 'Exception parsing '.$file->getName().': no places found to import', - array('app' => 'maps') - ); - } - - // Loop over all favorite entries - foreach($data['features'] as $key => $value) { - $this->currentFavorite = []; - - // Ensure that we have a valid GeoJSON Point geometry - if($value['geometry']['type'] !== "Point") { - $this->linesFound = true; - continue; - } - - // Read geometry - $this->currentFavorite['lng'] = floatval($value['geometry']['coordinates'][0]); - $this->currentFavorite['lat'] = floatval($value['geometry']['coordinates'][1]); - - $this->currentFavorite['name'] = $value['properties']['Title']; - $this->currentFavorite['category'] = $this->l10n->t('Personal'); - - $time = new \DateTime($value['properties']['Published']); - $this->currentFavorite['date_created'] = $time->getTimestamp(); - - $time = new \DateTime($value['properties']['Updated']); - $this->currentFavorite['date_modified'] = $time->getTimestamp(); - - if(isset($value['properties']['Location']['Address'])) { - $this->currentFavorite['comment'] = $value['properties']['Location']['Address']; - } - - - // Store this favorite - array_push($this->currentFavoritesList, $this->currentFavorite); - $this->nbImported++; - - // if we have enough favorites, we create them and clean the array - if (count($this->currentFavoritesList) >= 500) { - $this->addMultipleFavoritesToDB($this->importUserId, $this->currentFavoritesList); - unset($this->currentFavoritesList); - $this->currentFavoritesList = []; - } - } - - // Store last set of favorites - if (count($this->currentFavoritesList) > 0) { - $this->addMultipleFavoritesToDB($this->importUserId, $this->currentFavoritesList); - } - unset($this->currentFavoritesList); - - return [ - 'nbImported'=>$this->nbImported, - 'linesFound'=>$this->linesFound - ]; - } - - private function endswith($string, $test) { - $strlen = strlen($string); - $testlen = strlen($test); - if ($testlen > $strlen) return false; - return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0; - } + fwrite($fileHandler, $gpxHeader . "\n"); + + $chunkSize = 10000; + $favIndex = 0; + + while ($favIndex < $nbFavorites) { + $gpxText = ''; + + $qb->select('id', 'name', 'date_created', 'date_modified', 'lat', 'lng', 'category', 'comment', 'extensions') + ->from('maps_favorites', 'f') + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + if ($begin !== null) { + $qb->andWhere( + $qb->expr()->gte('date_created', $qb->createNamedParameter($begin, IQueryBuilder::PARAM_INT)) + ); + } + if ($end !== null) { + $qb->andWhere( + $qb->expr()->lte('date_created', $qb->createNamedParameter($end, IQueryBuilder::PARAM_INT)) + ); + } + // apply category restrictions if it's a non-empty array + if (!is_string($categoryList) and + is_array($categoryList) and + count($categoryList) > 0 + ) { + $or = $qb->expr()->orx(); + foreach ($categoryList as $cat) { + $or->add($qb->expr()->eq('category', $qb->createNamedParameter($cat, IQueryBuilder::PARAM_STR))); + } + $qb->andWhere($or); + } + $qb->orderBy('date_created', 'ASC') + ->setMaxResults($chunkSize) + ->setFirstResult($favIndex); + $req = $qb->execute(); + + while ($row = $req->fetch()) { + $name = str_replace('&', '&', $row['name']); + $epoch = $row['date_created']; + $date = ''; + if (is_numeric($epoch)) { + $epoch = intval($epoch); + $dt = new \DateTime("@$epoch"); + $date = $dt->format('Y-m-d\TH:i:s\Z'); + } + $lat = $row['lat']; + $lng = $row['lng']; + $category = str_replace('&', '&', $row['category']); + $comment = str_replace('&', '&', $row['comment']); + $extensions = str_replace('&', '&', $row['extensions']); + + $gpxExtension = ''; + $gpxText .= ' ' . "\n"; + $gpxText .= ' ' . $name . '' . "\n"; + $gpxText .= ' ' . "\n"; + if ($category !== null && strlen($category) > 0) { + $gpxText .= ' ' . $category . '' . "\n"; + } else { + $gpxText .= ' ' . $this->l10n->t('Personal') . '' . "\n"; + } + if ($comment !== null && strlen($comment) > 0) { + $gpxText .= ' ' . $comment . '' . "\n"; + } + if ($extensions !== null && strlen($extensions) > 0) { + $gpxExtension .= ' ' . $extensions . '' . "\n"; + } + if ($gpxExtension !== '') { + $gpxText .= ' ' . "\n" . $gpxExtension; + $gpxText .= ' ' . "\n"; + } + $gpxText .= ' ' . "\n"; + } + $req->closeCursor(); + $qb = $qb->resetQueryParts(); + // write the chunk ! + fwrite($fileHandler, $gpxText); + $favIndex = $favIndex + $chunkSize; + } + $gpxEnd = '' . "\n"; + fwrite($fileHandler, $gpxEnd); + } + + public function importFavorites($userId, $file) { + $lowerFileName = strtolower($file->getName()); + if ($this->endswith($lowerFileName, '.gpx')) { + return $this->importFavoritesFromGpx($userId, $file); + } elseif ($this->endswith($lowerFileName, '.kml')) { + $fp = $file->fopen('r'); + $name = $file->getName(); + return $this->importFavoritesFromKml($userId, $fp, $name); + } elseif ($this->endswith($lowerFileName, '.kmz')) { + return $this->importFavoritesFromKmz($userId, $file); + } elseif ($this->endswith($lowerFileName, '.json') or $this->endswith($lowerFileName, '.geojson')) { + return $this->importFavoritesFromGeoJSON($userId, $file); + } + } + + public function importFavoritesFromKmz($userId, $file) { + $path = $file->getStorage()->getLocalFile($file->getInternalPath()); + $name = $file->getName(); + $zf = new ZIP($path); + if (count($zf->getFiles()) > 0) { + $zippedFilePath = $zf->getFiles()[0]; + $fstream = $zf->getStream($zippedFilePath, 'r'); + + $result = $this->importFavoritesFromKml($userId, $fstream, $name); + } else { + $result = [ + 'nbImported' => 0, + 'linesFound' => false + ]; + } + return $result; + } + + public function importFavoritesFromKml($userId, $fp, $name) { + $this->nbImported = 0; + $this->linesFound = false; + $this->currentFavoritesList = []; + $this->importUserId = $userId; + $this->kmlInsidePlacemark = false; + $this->kmlCurrentCategory = ''; + + $xml_parser = xml_parser_create(); + xml_set_object($xml_parser, $this); + xml_set_element_handler($xml_parser, 'kmlStartElement', 'kmlEndElement'); + xml_set_character_data_handler($xml_parser, 'kmlDataElement'); + + // using xml_parse to be able to parse file chunks in case it's too big + while ($data = fread($fp, 4096000)) { + if (!xml_parse($xml_parser, $data, feof($fp))) { + $this->logger->error( + 'Exception in ' . $name . ' parsing at line ' . + xml_get_current_line_number($xml_parser) . ' : ' . + xml_error_string(xml_get_error_code($xml_parser)), + ['app' => 'maps'] + ); + return 0; + } + } + fclose($fp); + xml_parser_free($xml_parser); + + return [ + 'nbImported' => $this->nbImported, + 'linesFound' => $this->linesFound + ]; + } + + private function kmlStartElement($parser, $name, $attrs) { + $this->currentXmlTag = $name; + if ($name === 'PLACEMARK') { + $this->currentFavorite = []; + $this->kmlInsidePlacemark = true; + } + if ($name === 'LINESTRING') { + $this->linesFound = true; + } + } + + private function kmlEndElement($parser, $name) { + if ($name === 'KML') { + // create last bunch + if (count($this->currentFavoritesList) > 0) { + $this->addMultipleFavoritesToDB($this->importUserId, $this->currentFavoritesList); + } + unset($this->currentFavoritesList); + } elseif ($name === 'PLACEMARK') { + $this->kmlInsidePlacemark = false; + // store favorite + $this->nbImported++; + $this->currentFavorite['category'] = $this->kmlCurrentCategory; + if (!isset($this->currentFavorite['category']) or $this->currentFavorite['category'] === '') { + $this->currentFavorite['category'] = $this->l10n->t('Personal'); + } + // convert date + if (isset($this->currentFavorite['date_created'])) { + $time = new \DateTime($this->currentFavorite['date_created']); + $timestamp = $time->getTimestamp(); + $this->currentFavorite['date_created'] = $timestamp; + } + if (isset($this->currentFavorite['coordinates'])) { + $spl = explode(',', $this->currentFavorite['coordinates']); + if (count($spl) > 1) { + $this->currentFavorite['lat'] = floatval($spl[1]); + $this->currentFavorite['lng'] = floatval($spl[0]); + } + } + array_push($this->currentFavoritesList, $this->currentFavorite); + // if we have enough favorites, we create them and clean the array + if (count($this->currentFavoritesList) >= 500) { + $this->addMultipleFavoritesToDB($this->importUserId, $this->currentFavoritesList); + unset($this->currentFavoritesList); + $this->currentFavoritesList = []; + } + } + } + + private function kmlDataElement($parser, $data) { + $d = trim($data); + if (!empty($d)) { + if (!$this->kmlInsidePlacemark) { + if ($this->currentXmlTag === 'NAME') { + $this->kmlCurrentCategory = $this->kmlCurrentCategory . $d; + } + } else { + if ($this->currentXmlTag === 'NAME') { + $this->currentFavorite['name'] = (isset($this->currentFavorite['name'])) ? $this->currentFavorite['name'] . $d : $d; + } elseif ($this->currentXmlTag === 'WHEN') { + $this->currentFavorite['date_created'] = (isset($this->currentFavorite['date_created'])) ? $this->currentFavorite['date_created'] . $d : $d; + } elseif ($this->currentXmlTag === 'COORDINATES') { + $this->currentFavorite['coordinates'] = (isset($this->currentFavorite['coordinates'])) ? $this->currentFavorite['coordinates'] . $d : $d; + } elseif ($this->currentXmlTag === 'DESCRIPTION') { + $this->currentFavorite['comment'] = (isset($this->currentFavorite['comment'])) ? $this->currentFavorite['comment'] . $d : $d; + } + } + } + } + + public function importFavoritesFromGpx($userId, $file) { + $this->nbImported = 0; + $this->linesFound = false; + $this->currentFavoritesList = []; + $this->importUserId = $userId; + $this->insideWpt = false; + + $xml_parser = xml_parser_create(); + xml_set_object($xml_parser, $this); + xml_set_element_handler($xml_parser, 'gpxStartElement', 'gpxEndElement'); + xml_set_character_data_handler($xml_parser, 'gpxDataElement'); + + $fp = $file->fopen('r'); + + // using xml_parse to be able to parse file chunks in case it's too big + while ($data = fread($fp, 4096000)) { + if (!xml_parse($xml_parser, $data, feof($fp))) { + $this->logger->error( + 'Exception in ' . $file->getName() . ' parsing at line ' . + xml_get_current_line_number($xml_parser) . ' : ' . + xml_error_string(xml_get_error_code($xml_parser)), + ['app' => 'maps'] + ); + return 0; + } + } + fclose($fp); + xml_parser_free($xml_parser); + + return [ + 'nbImported' => $this->nbImported, + 'linesFound' => $this->linesFound + ]; + } + + private function gpxStartElement($parser, $name, $attrs) { + $this->currentXmlTag = $name; + if ($name === 'WPT') { + $this->insideWpt = true; + $this->currentFavorite = []; + if (isset($attrs['LAT'])) { + $this->currentFavorite['lat'] = floatval($attrs['LAT']); + } + if (isset($attrs['LON'])) { + $this->currentFavorite['lng'] = floatval($attrs['LON']); + } + } + if ($name === 'TRK' or $name === 'RTE') { + $this->linesFound = true; + } + } + + private function gpxEndElement($parser, $name) { + if ($name === 'GPX') { + // create last bunch + if (count($this->currentFavoritesList) > 0) { + $this->addMultipleFavoritesToDB($this->importUserId, $this->currentFavoritesList); + } + unset($this->currentFavoritesList); + } elseif ($name === 'WPT') { + $this->insideWpt = false; + // store favorite + $this->nbImported++; + // convert date + if (isset($this->currentFavorite['date_created'])) { + $time = new \DateTime($this->currentFavorite['date_created']); + $timestamp = $time->getTimestamp(); + $this->currentFavorite['date_created'] = $timestamp; + } + if (!isset($this->currentFavorite['category']) or $this->currentFavorite['category'] === '') { + $this->currentFavorite['category'] = $this->l10n->t('Personal'); + } + array_push($this->currentFavoritesList, $this->currentFavorite); + // if we have enough favorites, we create them and clean the array + if (count($this->currentFavoritesList) >= 500) { + $this->addMultipleFavoritesToDB($this->importUserId, $this->currentFavoritesList); + unset($this->currentFavoritesList); + $this->currentFavoritesList = []; + } + } + } + + private function gpxDataElement($parser, $data) { + $d = trim($data); + if (!empty($d)) { + if ($this->insideWpt and $this->currentXmlTag === 'NAME') { + $this->currentFavorite['name'] = (isset($this->currentFavorite['name'])) ? $this->currentFavorite['name'] . $d : $d; + } elseif ($this->insideWpt and $this->currentXmlTag === 'TIME') { + $this->currentFavorite['date_created'] = (isset($this->currentFavorite['date_created'])) ? $this->currentFavorite['date_created'] . $d : $d; + } elseif ($this->insideWpt and $this->currentXmlTag === 'TYPE') { + $this->currentFavorite['category'] = (isset($this->currentFavorite['category'])) ? $this->currentFavorite['category'] . $d : $d; + } elseif ($this->insideWpt and $this->currentXmlTag === 'DESC') { + $this->currentFavorite['comment'] = (isset($this->currentFavorite['comment'])) ? $this->currentFavorite['comment'] . $d : $d; + } elseif ($this->insideWpt and $this->currentXmlTag === 'MAPS-EXTENSIONS') { + $this->currentFavorite['extensions'] = (isset($this->currentFavorite['extensions'])) ? $this->currentFavorite['extensions'] . $d : $d; + } + } + } + + public function importFavoritesFromGeoJSON($userId, $file) { + $this->nbImported = 0; + $this->linesFound = false; + $this->currentFavoritesList = []; + $this->importUserId = $userId; + + + // Decode file content from JSON + $data = json_decode($file->getContent(), true, 512); + + if ($data == null or !isset($data['features'])) { + $this->logger->error( + 'Exception parsing '.$file->getName().': no places found to import', + ['app' => 'maps'] + ); + } + + // Loop over all favorite entries + foreach ($data['features'] as $key => $value) { + $this->currentFavorite = []; + + // Ensure that we have a valid GeoJSON Point geometry + if ($value['geometry']['type'] !== 'Point') { + $this->linesFound = true; + continue; + } + + // Read geometry + $this->currentFavorite['lng'] = floatval($value['geometry']['coordinates'][0]); + $this->currentFavorite['lat'] = floatval($value['geometry']['coordinates'][1]); + + $this->currentFavorite['name'] = $value['properties']['Title']; + $this->currentFavorite['category'] = $this->l10n->t('Personal'); + + $time = new \DateTime($value['properties']['Published']); + $this->currentFavorite['date_created'] = $time->getTimestamp(); + + $time = new \DateTime($value['properties']['Updated']); + $this->currentFavorite['date_modified'] = $time->getTimestamp(); + + if (isset($value['properties']['Location']['Address'])) { + $this->currentFavorite['comment'] = $value['properties']['Location']['Address']; + } + + + // Store this favorite + array_push($this->currentFavoritesList, $this->currentFavorite); + $this->nbImported++; + + // if we have enough favorites, we create them and clean the array + if (count($this->currentFavoritesList) >= 500) { + $this->addMultipleFavoritesToDB($this->importUserId, $this->currentFavoritesList); + unset($this->currentFavoritesList); + $this->currentFavoritesList = []; + } + } + + // Store last set of favorites + if (count($this->currentFavoritesList) > 0) { + $this->addMultipleFavoritesToDB($this->importUserId, $this->currentFavoritesList); + } + unset($this->currentFavoritesList); + + return [ + 'nbImported' => $this->nbImported, + 'linesFound' => $this->linesFound + ]; + } + + private function endswith($string, $test) { + $strlen = strlen($string); + $testlen = strlen($test); + if ($testlen > $strlen) { + return false; + } + return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0; + } } diff --git a/lib/Service/GeophotoService.php b/lib/Service/GeophotoService.php index 70aff8890..2d8e1f96d 100644 --- a/lib/Service/GeophotoService.php +++ b/lib/Service/GeophotoService.php @@ -16,77 +16,71 @@ use OC\Files\Search\SearchComparison; use OC\Files\Search\SearchQuery; use OC\User\NoUserException; +use OCA\Maps\DB\GeophotoMapper; use OCP\DB\Exception; -use OCP\Files\FileInfo; +use OCP\Files\Folder; +use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\Files\Search\ISearchBinaryOperator; use OCP\Files\Search\ISearchComparison; use OCP\ICacheFactory; use OCP\IL10N; -use OCP\Files\IRootFolder; -use OCP\Files\Storage\IStorage; -use OCP\Files\Folder; -use OCP\IPreview; use OCP\ILogger; -use OCA\Maps\Service\PhotofilesService; -use OCA\Maps\DB\Geophoto; -use OCA\Maps\DB\GeophotoMapper; -use OCA\Maps\Service\TracksService; -use OCA\Maps\Service\DevicesService; +use OCP\IPreview; class GeophotoService { - private $l10n; - private $root; - private $photoMapper; - private $logger; - private $preview; - private $tracksService; - private $timeorderedPointSets; - private $devicesService; + private $l10n; + private $root; + private $photoMapper; + private $logger; + private $preview; + private $tracksService; + private $timeorderedPointSets; + private $devicesService; private $cacheFactory; private $userId; private \OCP\ICache $photosCache; private \OCP\ICache $timeOrderedPointSetsCache; private \OCP\ICache $backgroundJobCache; - public function __construct (ILogger $logger, - IRootFolder $root, - IL10N $l10n, - GeophotoMapper $photoMapper, - IPreview $preview, - TracksService $tracksService, - DevicesService $devicesService, - ICacheFactory $cacheFactory, - $userId) { - $this->root = $root; - $this->l10n = $l10n; - $this->photoMapper = $photoMapper; - $this->logger = $logger; - $this->preview = $preview; - $this->tracksService = $tracksService; - $this->timeorderedPointSets = null; - $this->userId = $userId; - $this->devicesService = $devicesService; + public function __construct(ILogger $logger, + IRootFolder $root, + IL10N $l10n, + GeophotoMapper $photoMapper, + IPreview $preview, + TracksService $tracksService, + DevicesService $devicesService, + ICacheFactory $cacheFactory, + $userId) { + $this->root = $root; + $this->l10n = $l10n; + $this->photoMapper = $photoMapper; + $this->logger = $logger; + $this->preview = $preview; + $this->tracksService = $tracksService; + $this->timeorderedPointSets = null; + $this->userId = $userId; + $this->devicesService = $devicesService; $this->cacheFactory = $cacheFactory; $this->photosCache = $this->cacheFactory->createDistributed('maps:photos'); $this->timeOrderedPointSetsCache = $this->cacheFactory->createDistributed('maps:time-ordered-point-sets'); $this->backgroundJobCache = $this->cacheFactory->createDistributed('maps:background-jobs'); - } + } /** * @param string $userId * @return bool */ - public function clearCache(string $userId=''): bool { - $a = $this->photosCache->clear($userId); - $b = $this->timeOrderedPointSetsCache->clear($userId); - $c = $this->backgroundJobCache->clear('recentlyAdded:'.$userId); - $d = $this->backgroundJobCache->clear('recentlyUpdated:'.$userId); - return $a and $b and $c and $d; + public function clearCache(string $userId = ''): bool { + $a = $this->photosCache->clear($userId); + $b = $this->timeOrderedPointSetsCache->clear($userId); + $c = $this->backgroundJobCache->clear('recentlyAdded:'.$userId); + $d = $this->backgroundJobCache->clear('recentlyUpdated:'.$userId); + return $a and $b and $c and $d; } /** @@ -101,77 +95,77 @@ public function clearCache(string $userId=''): bool { * @throws NotFoundException * @throws NotPermittedException */ - public function getAll(string $userId, $folder=null, bool $respectNomediaAndNoimage=true, bool $hideImagesOnCustomMaps=false, bool $hideImagesInMapsFolder=true): array { - $userFolder = $this->getFolderForUser($userId); - if (is_null($folder)) { - $folder = $userFolder; - } - $key = $userId . ':' . $userFolder->getRelativePath($folder->getPath()) . ':' . (string) $respectNomediaAndNoimage . ':' . (string) $hideImagesOnCustomMaps . ':' . (string) $hideImagesInMapsFolder; - $filesById = $this->photosCache->get($key); - if ($filesById === null) { - $ignoredPaths = $respectNomediaAndNoimage ? $this->getIgnoredPaths($userId, $folder, $hideImagesOnCustomMaps) : []; - if ($hideImagesInMapsFolder) { - $ignoredPaths[] = "/Maps"; - } - $photoEntities = $this->photoMapper->findAll($userId); + public function getAll(string $userId, $folder = null, bool $respectNomediaAndNoimage = true, bool $hideImagesOnCustomMaps = false, bool $hideImagesInMapsFolder = true): array { + $userFolder = $this->getFolderForUser($userId); + if (is_null($folder)) { + $folder = $userFolder; + } + $key = $userId . ':' . $userFolder->getRelativePath($folder->getPath()) . ':' . (string)$respectNomediaAndNoimage . ':' . (string)$hideImagesOnCustomMaps . ':' . (string)$hideImagesInMapsFolder; + $filesById = $this->photosCache->get($key); + if ($filesById === null) { + $ignoredPaths = $respectNomediaAndNoimage ? $this->getIgnoredPaths($userId, $folder, $hideImagesOnCustomMaps) : []; + if ($hideImagesInMapsFolder) { + $ignoredPaths[] = '/Maps'; + } + $photoEntities = $this->photoMapper->findAll($userId); - $filesById = []; - $cache = $folder->getStorage()->getCache(); - $previewEnableMimetypes = $this->getPreviewEnabledMimetypes(); - foreach ($photoEntities as $photoEntity) { - $cacheEntry = $cache->get($photoEntity->getFileId()); - if ($cacheEntry) { - // this path is relative to owner's storage - //$path = $cacheEntry->getPath(); - //but we want it relative to current user's storage - $files = $folder->getById($photoEntity->getFileId()); - if (empty($files)) { - continue; - } - $file = array_shift($files); - if ($file === null) { - continue; - } - $path = $userFolder->getRelativePath($file->getPath()); - $isIgnored = false; - foreach ($ignoredPaths as $ignoredPath) { - if (str_starts_with($path, $ignoredPath)) { - $isIgnored = true; - break; - } - } - if (!$isIgnored) { - $isRoot = $file === $userFolder; + $filesById = []; + $cache = $folder->getStorage()->getCache(); + $previewEnableMimetypes = $this->getPreviewEnabledMimetypes(); + foreach ($photoEntities as $photoEntity) { + $cacheEntry = $cache->get($photoEntity->getFileId()); + if ($cacheEntry) { + // this path is relative to owner's storage + //$path = $cacheEntry->getPath(); + //but we want it relative to current user's storage + $files = $folder->getById($photoEntity->getFileId()); + if (empty($files)) { + continue; + } + $file = array_shift($files); + if ($file === null) { + continue; + } + $path = $userFolder->getRelativePath($file->getPath()); + $isIgnored = false; + foreach ($ignoredPaths as $ignoredPath) { + if (str_starts_with($path, $ignoredPath)) { + $isIgnored = true; + break; + } + } + if (!$isIgnored) { + $isRoot = $file === $userFolder; - $file_object = new \stdClass(); - $file_object->fileId = $photoEntity->getFileId(); - $file_object->fileid = $file_object->fileId; - $file_object->lat = $photoEntity->getLat(); - $file_object->lng = $photoEntity->getLng(); - $file_object->dateTaken = $photoEntity->getDateTaken() ?? \time(); - $file_object->basename = $isRoot ? '' : $file->getName(); - $file_object->filename = $this->normalizePath($path); - $file_object->etag = $cacheEntry->getEtag(); - //Not working for NC21 as Viewer requires String representation of permissions - // $file_object->permissions = $file->getPermissions(); - $file_object->type = $file->getType(); - $file_object->mime = $file->getMimetype(); - $file_object->lastmod = $file->getMTime(); - $file_object->size = $file->getSize(); - $file_object->path = $path; - $file_object->isReadable = $file->isReadable(); - $file_object->isUpdateable = $file->isUpdateable(); - $file_object->isShareable = $file->isShareable(); - $file_object->isDeletable = $file->isDeletable(); - $file_object->hasPreview = in_array($cacheEntry->getMimeType(), $previewEnableMimetypes); - $filesById[] = $file_object; - } - } - } - $this->photosCache->set($key, $filesById, 60 * 60 * 24); - } - return $filesById; - } + $file_object = new \stdClass(); + $file_object->fileId = $photoEntity->getFileId(); + $file_object->fileid = $file_object->fileId; + $file_object->lat = $photoEntity->getLat(); + $file_object->lng = $photoEntity->getLng(); + $file_object->dateTaken = $photoEntity->getDateTaken() ?? \time(); + $file_object->basename = $isRoot ? '' : $file->getName(); + $file_object->filename = $this->normalizePath($path); + $file_object->etag = $cacheEntry->getEtag(); + //Not working for NC21 as Viewer requires String representation of permissions + // $file_object->permissions = $file->getPermissions(); + $file_object->type = $file->getType(); + $file_object->mime = $file->getMimetype(); + $file_object->lastmod = $file->getMTime(); + $file_object->size = $file->getSize(); + $file_object->path = $path; + $file_object->isReadable = $file->isReadable(); + $file_object->isUpdateable = $file->isUpdateable(); + $file_object->isShareable = $file->isShareable(); + $file_object->isDeletable = $file->isDeletable(); + $file_object->hasPreview = in_array($cacheEntry->getMimeType(), $previewEnableMimetypes); + $filesById[] = $file_object; + } + } + } + $this->photosCache->set($key, $filesById, 60 * 60 * 24); + } + return $filesById; + } /** * @param string $userId @@ -188,7 +182,7 @@ public function getAll(string $userId, $folder=null, bool $respectNomediaAndNoim * @throws NotFoundException * @throws NotPermittedException */ - public function getNonLocalized (string $userId, $folder=null, bool $respectNomediaAndNoimage=true, bool $hideImagesOnCustomMaps=false, bool $hideImagesInMapsFolder=true, string $timezone=null, int $limit=250, int $offset=0): array { + public function getNonLocalized(string $userId, $folder = null, bool $respectNomediaAndNoimage = true, bool $hideImagesOnCustomMaps = false, bool $hideImagesInMapsFolder = true, ?string $timezone = null, int $limit = 250, int $offset = 0): array { $userFolder = $this->getFolderForUser($userId); if (is_null($folder)) { $folder = $userFolder; @@ -196,7 +190,7 @@ public function getNonLocalized (string $userId, $folder=null, bool $respectNome $ignoredPaths = $respectNomediaAndNoimage ? $this->getIgnoredPaths($userId, $folder, $hideImagesOnCustomMaps) : []; if ($hideImagesInMapsFolder) { - $ignoredPaths[] = "/Maps"; + $ignoredPaths[] = '/Maps'; } $this->loadTimeorderedPointSets($userId, $folder, $respectNomediaAndNoimage, $hideImagesOnCustomMaps, $hideImagesInMapsFolder); $photoEntities = $this->photoMapper->findAllNonLocalized($userId, $limit, $offset); @@ -263,7 +257,7 @@ public function getNonLocalized (string $userId, $folder=null, bool $respectNome $file_object->isDeletable = $file->isDeletable(); $file_object->hasPreview = in_array($cacheEntry->getMimeType(), $previewEnableMimetypes); $file_object->trackOrDeviceId = $key; - if(!array_key_exists($key, $suggestionsBySource)){ + if (!array_key_exists($key, $suggestionsBySource)) { $suggestionsBySource[$key] = []; } $suggestionsBySource[$key][] = $file_object; @@ -271,8 +265,8 @@ public function getNonLocalized (string $userId, $folder=null, bool $respectNome } } } - return $suggestionsBySource; - } + return $suggestionsBySource; + } /** * @param $userId @@ -282,9 +276,9 @@ public function getNonLocalized (string $userId, $folder=null, bool $respectNome * @throws \OCP\Files\NotPermittedException * @throws \OC\User\NoUserException */ - private function getIgnoredPaths($userId, $folder=null, $hideImagesOnCustomMaps=true){ + private function getIgnoredPaths($userId, $folder = null, $hideImagesOnCustomMaps = true) { $ignoredPaths = []; - $userFolder=$this->getFolderForUser($userId); + $userFolder = $this->getFolderForUser($userId); if (is_null($folder)) { $folder = $userFolder; } @@ -296,48 +290,48 @@ private function getIgnoredPaths($userId, $folder=null, $hideImagesOnCustomMaps= if ($hideImagesOnCustomMaps) { $ignoreFileMimetypes[] = 'application/x-nextcloud-maps'; } - $func = function(string $i): SearchComparison { + $func = function (string $i): SearchComparison { return new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', $i); }; $excludedNodes = $folder->search(new SearchQuery( - new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, array_map( - $func, - $ignoreFileMimetypes) - ), + new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, array_map( + $func, + $ignoreFileMimetypes) + ), 0, 0, [] )); - foreach($excludedNodes as $node) { + foreach ($excludedNodes as $node) { $ignoredPaths[] = $userFolder->getRelativePath($node->getParent()->getPath()); } return $ignoredPaths; } - /** - * returns a array of locations for a given date - * - * @param $dateTaken int - * @return array - */ - private function getLocationGuesses(int $dateTaken): array { - $locations = []; - foreach (($this->timeorderedPointSets ?? []) as $key => $timeordedPointSet) { - $location = $this->getLocationFromSequenceOfPoints($dateTaken,$timeordedPointSet); - if (!is_null($location)) { - $locations[$key] = $location; - } - } - return $locations; + /** + * returns a array of locations for a given date + * + * @param $dateTaken int + * @return array + */ + private function getLocationGuesses(int $dateTaken): array { + $locations = []; + foreach (($this->timeorderedPointSets ?? []) as $key => $timeordedPointSet) { + $location = $this->getLocationFromSequenceOfPoints($dateTaken, $timeordedPointSet); + if (!is_null($location)) { + $locations[$key] = $location; + } + } + return $locations; - } + } - /* - * Timeordered Point sets is an Array of Arrays with time => location as key=>value pair, which are orderd by the key. - * This function loads this Arrays from all Track files of the user. - */ - private function loadTimeorderedPointSets(string $userId, $folder=null, bool $respectNomediaAndNoimage=true, bool $hideTracksOnCustomMaps=false, bool $hideTracksInMapsFolder=true): void { - $key = $userId . ':' . (string) $respectNomediaAndNoimage . ':' . (string) $hideTracksOnCustomMaps . ':' . (string) $hideTracksInMapsFolder; + /* + * Timeordered Point sets is an Array of Arrays with time => location as key=>value pair, which are orderd by the key. + * This function loads this Arrays from all Track files of the user. + */ + private function loadTimeorderedPointSets(string $userId, $folder = null, bool $respectNomediaAndNoimage = true, bool $hideTracksOnCustomMaps = false, bool $hideTracksInMapsFolder = true): void { + $key = $userId . ':' . (string)$respectNomediaAndNoimage . ':' . (string)$hideTracksOnCustomMaps . ':' . (string)$hideTracksInMapsFolder; $this->timeorderedPointSets = $this->timeOrderedPointSetsCache->get($key); if (is_null($this->timeorderedPointSets)) { $userFolder = $this->getFolderForUser($userId); @@ -358,41 +352,41 @@ private function loadTimeorderedPointSets(string $userId, $folder=null, bool $re } $this->timeOrderedPointSetsCache->set($key, $this->timeorderedPointSets); } - } + } - /* - * A GPX file can contain multiple tracks this function returns all Tracks from a given sting containing GPX encoded information. - * @param $content - * @return array - */ - private function getTracksFromGPX($content): array { - $tracks = []; - $gpx = simplexml_load_string($content); - foreach ($gpx->trk as $trk) { - $tracks[] = $trk; - } - return $tracks; - } + /* + * A GPX file can contain multiple tracks this function returns all Tracks from a given sting containing GPX encoded information. + * @param $content + * @return array + */ + private function getTracksFromGPX($content): array { + $tracks = []; + $gpx = simplexml_load_string($content); + foreach ($gpx->trk as $trk) { + $tracks[] = $trk; + } + return $tracks; + } - /* - * Loads all trackpoints from a given $track SimpleXMLObject. And stores them in a time=>location stuctured array which is sorted by the key. - * @param $track - * @return array - */ - private function getTimeorderdPointsFromTrack($track): array { - $points = []; - foreach ($track->trkseg as $seg) { - foreach ($seg->trkpt as $pt) { - $points[strtotime($pt->time)] = [(string) $pt["lat"],(string) $pt["lon"]]; - } - } - foreach ($track->trkpt as $pt) { - $points[strtotime($pt->time)] = [(string) $pt["lat"],(string) $pt["lon"]]; - } + /* + * Loads all trackpoints from a given $track SimpleXMLObject. And stores them in a time=>location stuctured array which is sorted by the key. + * @param $track + * @return array + */ + private function getTimeorderdPointsFromTrack($track): array { + $points = []; + foreach ($track->trkseg as $seg) { + foreach ($seg->trkpt as $pt) { + $points[strtotime($pt->time)] = [(string)$pt['lat'],(string)$pt['lon']]; + } + } + foreach ($track->trkpt as $pt) { + $points[strtotime($pt->time)] = [(string)$pt['lat'],(string)$pt['lon']]; + } - $foo = ksort($points); - return $points; - } + $foo = ksort($points); + return $points; + } /** * @param int $timeUTC @@ -404,59 +398,59 @@ private function getLocalTime(int $timeUTC, float $lat, float $lng) { } - /** - * @param $dateTaken int timestamp of the picture - * @param $points array sorted by keys timestamp => [lat, lng] - */ - private function getLocationFromSequenceOfPoints(int $dateTaken, array $points): ?array { - $foo = end($points); - $end = key($points); - $foo = reset($points); - $start = key($points); - if ($start > $dateTaken OR $end < $dateTaken) { - return null; - } - $smaller = null; - $bigger = null; - foreach ($points as $time => $locations) { - if ($time < $dateTaken) { - $smaller = $time; - } else { - $bigger = $time; - break; - } - } - if (!is_null($smaller) AND !is_null($bigger)) { - $d = $bigger - $smaller; - $t = ($dateTaken - $smaller) / $d; - $latd = $points[$bigger][0] - $points[$smaller][0]; - $lngd = $points[$bigger][1] - $points[$smaller][1]; - return [$points[$smaller][0] + $t * $latd, $points[$smaller][1] + $t * $lngd]; - } else { - return null; - } - } + /** + * @param $dateTaken int timestamp of the picture + * @param $points array sorted by keys timestamp => [lat, lng] + */ + private function getLocationFromSequenceOfPoints(int $dateTaken, array $points): ?array { + $foo = end($points); + $end = key($points); + $foo = reset($points); + $start = key($points); + if ($start > $dateTaken or $end < $dateTaken) { + return null; + } + $smaller = null; + $bigger = null; + foreach ($points as $time => $locations) { + if ($time < $dateTaken) { + $smaller = $time; + } else { + $bigger = $time; + break; + } + } + if (!is_null($smaller) and !is_null($bigger)) { + $d = $bigger - $smaller; + $t = ($dateTaken - $smaller) / $d; + $latd = $points[$bigger][0] - $points[$smaller][0]; + $lngd = $points[$bigger][1] - $points[$smaller][1]; + return [$points[$smaller][0] + $t * $latd, $points[$smaller][1] + $t * $lngd]; + } else { + return null; + } + } - private function getPreviewEnabledMimetypes(): array { - $enabledMimeTypes = []; - foreach (PhotofilesService::PHOTO_MIME_TYPES as $mimeType) { - if ($this->preview->isMimeSupported($mimeType)) { - $enabledMimeTypes[] = $mimeType; - } - } - return $enabledMimeTypes; - } + private function getPreviewEnabledMimetypes(): array { + $enabledMimeTypes = []; + foreach (PhotofilesService::PHOTO_MIME_TYPES as $mimeType) { + if ($this->preview->isMimeSupported($mimeType)) { + $enabledMimeTypes[] = $mimeType; + } + } + return $enabledMimeTypes; + } - private function normalizePath($path) { - return str_replace("files","", $path); - } + private function normalizePath($path) { + return str_replace('files', '', $path); + } - /** - * @param string $userId the user id - * @return Folder - */ - private function getFolderForUser ($userId) { + /** + * @param string $userId the user id + * @return Folder + */ + private function getFolderForUser($userId) { return $this->root->getUserFolder($userId); - } + } } diff --git a/lib/Service/MimetypeService.php b/lib/Service/MimetypeService.php index 2ae0a8987..fc42ccfa5 100644 --- a/lib/Service/MimetypeService.php +++ b/lib/Service/MimetypeService.php @@ -6,17 +6,15 @@ class MimetypeService { - const CUSTOM_MIMETYPEMAPPING = 'mimetypemapping.json'; + public const CUSTOM_MIMETYPEMAPPING = 'mimetypemapping.json'; protected IMimeTypeLoader $mimeTypeLoader; - public function __construct(IMimeTypeLoader $mimeTypeLoader) - { + public function __construct(IMimeTypeLoader $mimeTypeLoader) { $this->mimeTypeLoader = $mimeTypeLoader; } - public function registerForExistingFiles() - { + public function registerForExistingFiles() { $mimeTypeId = $this->mimeTypeLoader->getId('application/x-nextcloud-maps'); $this->mimeTypeLoader->updateFilecache('maps', $mimeTypeId); @@ -33,8 +31,7 @@ public function registerForExistingFiles() $this->mimeTypeLoader->updateFilecache('notrack', $mimeTypeId); } - public function registerForNewFiles() - { + public function registerForNewFiles() { $mapping = [ 'maps' => ['application/x-nextcloud-maps'], 'noindex' => ['application/x-nextcloud-noindex'], diff --git a/lib/Service/MyMapsService.php b/lib/Service/MyMapsService.php index ecf9237fb..c0a2360aa 100644 --- a/lib/Service/MyMapsService.php +++ b/lib/Service/MyMapsService.php @@ -12,132 +12,118 @@ namespace OCA\Maps\Service; -use OC\Files\Search\SearchBinaryOperator; use OC\Files\Search\SearchComparison; use OC\Files\Search\SearchQuery; use OC\OCS\Exception; use OC\User\NoUserException; -use OCP\Files\InvalidPathException; -use OCP\Files\NotPermittedException; -use OCP\Files\Search\ISearchQuery; -use OCP\AppFramework\Http\DataResponse; +use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; -use OCP\Files\Search\ISearchBinaryOperator; +use OCP\Files\NotPermittedException; use OCP\Files\Search\ISearchComparison; -use OCP\IL10N; use OCP\ILogger; -use OCP\DB\QueryBuilder\IQueryBuilder; -use OCP\Files\IRootFolder; -use OCP\Files\FileInfo; -use OCP\Share\IManager; -use OCP\Files\Folder; -use OCP\Files\Node; class MyMapsService { - private $logger; + private $logger; private $root; - public function __construct (ILogger $logger, IRootFolder $root) { - $this->logger = $logger; + public function __construct(ILogger $logger, IRootFolder $root) { + $this->logger = $logger; $this->root = $root; - } + } - public function addMyMap($newName, $userId, $counter=0) { + public function addMyMap($newName, $userId, $counter = 0) { $userFolder = $this->root->getUserFolder($userId); - if (!$userFolder->nodeExists('/Maps')) { + if (!$userFolder->nodeExists('/Maps')) { $userFolder->newFolder('Maps'); - } - if ($userFolder->nodeExists('/Maps')) { - $mapsFolder = $userFolder->get('/Maps'); - if ($mapsFolder->getType() !== \OCP\Files\FileInfo::TYPE_FOLDER) { - $response = '/Maps is not a directory'; - return $response; - } - else if (!$mapsFolder->isCreatable()) { - $response = '/Maps is not writeable'; - return $response; - } - } - else { - $response = 'Impossible to create /Maps'; - return $response; - } - if ($counter>0) { - $folderName = $newName." ".$counter; - } - else { - $folderName = $newName; - } + } + if ($userFolder->nodeExists('/Maps')) { + $mapsFolder = $userFolder->get('/Maps'); + if ($mapsFolder->getType() !== \OCP\Files\FileInfo::TYPE_FOLDER) { + $response = '/Maps is not a directory'; + return $response; + } elseif (!$mapsFolder->isCreatable()) { + $response = '/Maps is not writeable'; + return $response; + } + } else { + $response = 'Impossible to create /Maps'; + return $response; + } + if ($counter > 0) { + $folderName = $newName.' '.$counter; + } else { + $folderName = $newName; + } - if ($mapsFolder->nodeExists($folderName)) { - return $this->addMyMap($newName, $userId,$counter+1); - } - $mapFolder = $mapsFolder->newFolder($folderName); - $mapFolder->newFile(".index.maps","{}"); + if ($mapsFolder->nodeExists($folderName)) { + return $this->addMyMap($newName, $userId, $counter + 1); + } + $mapFolder = $mapsFolder->newFolder($folderName); + $mapFolder->newFile('.index.maps', '{}'); $isRoot = $mapFolder->getPath() === $userFolder->getPath(); $MyMap = [ - "id"=>$mapFolder->getId(), - "name"=>$folderName, - "color"=>null, - "path"=>$userFolder->getRelativePath($mapFolder->getPath()), - "isShareable"=>$mapFolder->isShareable(), - "isDeletable"=>$mapFolder->isDeletable(), - "isCreatable"=>$mapFolder->isCreatable(), - "isUpdateable"=>$mapFolder->isUpdateable(), - "isReadable"=>$mapFolder->isReadable(), - "fileInfo"=>[ - "id" => $mapFolder->getId(), - "name" => "", - "basename" => $isRoot ? '' : $mapFolder->getName(), - "filename" => $userFolder->getRelativePath($mapFolder->getPath()), - "etag" => $mapFolder->getEtag(), - "permissions" => $mapFolder->getPermissions(), - "type" => $mapFolder->getType(), - "mime" => $mapFolder->getMimetype(), - "lastmod" => $mapFolder->getMTime(), - "path"=>$userFolder->getRelativePath($mapFolder->getPath()), - "sharePermissions"=>$mapFolder->getPermissions(), + 'id' => $mapFolder->getId(), + 'name' => $folderName, + 'color' => null, + 'path' => $userFolder->getRelativePath($mapFolder->getPath()), + 'isShareable' => $mapFolder->isShareable(), + 'isDeletable' => $mapFolder->isDeletable(), + 'isCreatable' => $mapFolder->isCreatable(), + 'isUpdateable' => $mapFolder->isUpdateable(), + 'isReadable' => $mapFolder->isReadable(), + 'fileInfo' => [ + 'id' => $mapFolder->getId(), + 'name' => '', + 'basename' => $isRoot ? '' : $mapFolder->getName(), + 'filename' => $userFolder->getRelativePath($mapFolder->getPath()), + 'etag' => $mapFolder->getEtag(), + 'permissions' => $mapFolder->getPermissions(), + 'type' => $mapFolder->getType(), + 'mime' => $mapFolder->getMimetype(), + 'lastmod' => $mapFolder->getMTime(), + 'path' => $userFolder->getRelativePath($mapFolder->getPath()), + 'sharePermissions' => $mapFolder->getPermissions(), ] ]; - return $MyMap; - } + return $MyMap; + } - private function node2MyMap($node, $userFolder):array{ + private function node2MyMap($node, $userFolder):array { $mapData = json_decode($node->getContent(), true); - if (isset($mapData["name"])) { - $name = $mapData["name"]; + if (isset($mapData['name'])) { + $name = $mapData['name']; } else { $name = $node->getParent()->getName(); } $color = null; - if (isset($mapData["color"])) { - $color = $mapData["color"]; + if (isset($mapData['color'])) { + $color = $mapData['color']; } $parentNode = $node->getParent(); $isRoot = $parentNode->getPath() === $userFolder->getPath(); $MyMap = [ - "id" => $parentNode->getId(), - "name" => $name, - "color" => $color, - "path" => $userFolder->getRelativePath($parentNode->getPath()), - "isShareable" => $parentNode->isShareable(), - "isDeletable" => $parentNode->isDeletable(), - "isCreatable" => $parentNode->isCreatable(), - "isUpdateable" => $parentNode->isUpdateable(), - "isReadable" => $parentNode->isReadable(), - "fileInfo" => [ - "id" => $parentNode->getId(), - "name" => "", - "basename" => $isRoot ? '' : $parentNode->getName(), - "filename" => $userFolder->getRelativePath($parentNode->getPath()), - "etag" => $parentNode->getEtag(), - "permissions" => $parentNode->getPermissions(), - "type" => $parentNode->getType(), - "mime" => $parentNode->getMimetype(), - "lastmod" => $parentNode->getMTime(), - "path" => $userFolder->getRelativePath($parentNode->getPath()), - "sharePermissions" => $parentNode->getPermissions(), + 'id' => $parentNode->getId(), + 'name' => $name, + 'color' => $color, + 'path' => $userFolder->getRelativePath($parentNode->getPath()), + 'isShareable' => $parentNode->isShareable(), + 'isDeletable' => $parentNode->isDeletable(), + 'isCreatable' => $parentNode->isCreatable(), + 'isUpdateable' => $parentNode->isUpdateable(), + 'isReadable' => $parentNode->isReadable(), + 'fileInfo' => [ + 'id' => $parentNode->getId(), + 'name' => '', + 'basename' => $isRoot ? '' : $parentNode->getName(), + 'filename' => $userFolder->getRelativePath($parentNode->getPath()), + 'etag' => $parentNode->getEtag(), + 'permissions' => $parentNode->getPermissions(), + 'type' => $parentNode->getType(), + 'mime' => $parentNode->getMimetype(), + 'lastmod' => $parentNode->getMTime(), + 'path' => $userFolder->getRelativePath($parentNode->getPath()), + 'sharePermissions' => $parentNode->getPermissions(), ] ]; return $MyMap; @@ -149,7 +135,7 @@ private function node2MyMap($node, $userFolder):array{ * @throws NoUserException * @throws NotPermittedException */ - public function getAllMyMaps($userId){ + public function getAllMyMaps($userId) { $userFolder = $this->root->getUserFolder($userId); $MyMaps = []; $MyMapsNodes = $userFolder->search(new SearchQuery( @@ -157,65 +143,65 @@ public function getAllMyMaps($userId){ 0, 0, [])); foreach ($MyMapsNodes as $node) { - if ($node->getName() === ".index.maps") { + if ($node->getName() === '.index.maps') { $MyMaps[] = $this->node2MyMap($node, $userFolder); } } return $MyMaps; - } + } - public function updateMyMap($id, $values, $userId) { + public function updateMyMap($id, $values, $userId) { $userFolder = $this->root->getUserFolder($userId); - $folders = $userFolder->getById($id); - $folder = array_shift($folders); - try { - $file=$folder->get(".index.maps"); - } catch (NotFoundException $e) { - $file=$folder->newFile(".index.maps", $content = '{}'); - } - $mapData = json_decode($file->getContent(),true); - $renamed = false; - foreach ($values as $key=>$value) { - if ($key === 'newName') { - $key = 'name'; - $newName = $value; - $renamed = true; - } - if (is_null($value)) { - unset($mapData[$key]); - } else { - $mapData[$key] = $value; - } - } - $file->putContent(json_encode($mapData,JSON_PRETTY_PRINT)); - if ($renamed) { - if ($userFolder->nodeExists('/Maps')) { - $mapsFolder = $userFolder->get('/Maps'); - if ($folder->getParent()->getId() === $mapsFolder->getId() ) { - try { - $folder->move($mapsFolder->getPath()."/".$newName); - } catch (Exception $e) { - } - } - } - } - return $mapData; - } + $folders = $userFolder->getById($id); + $folder = array_shift($folders); + try { + $file = $folder->get('.index.maps'); + } catch (NotFoundException $e) { + $file = $folder->newFile('.index.maps', $content = '{}'); + } + $mapData = json_decode($file->getContent(), true); + $renamed = false; + foreach ($values as $key => $value) { + if ($key === 'newName') { + $key = 'name'; + $newName = $value; + $renamed = true; + } + if (is_null($value)) { + unset($mapData[$key]); + } else { + $mapData[$key] = $value; + } + } + $file->putContent(json_encode($mapData, JSON_PRETTY_PRINT)); + if ($renamed) { + if ($userFolder->nodeExists('/Maps')) { + $mapsFolder = $userFolder->get('/Maps'); + if ($folder->getParent()->getId() === $mapsFolder->getId()) { + try { + $folder->move($mapsFolder->getPath().'/'.$newName); + } catch (Exception $e) { + } + } + } + } + return $mapData; + } - public function deleteMyMap($id, $userId) { + public function deleteMyMap($id, $userId) { $userFolder = $this->root->getUserFolder($userId); - $folders = $userFolder->getById($id); - $folder = array_shift($folders); - if ($userFolder->nodeExists('/Maps')) { - $mapsFolder = $userFolder->get('/Maps'); - if ($folder->getParent()->getId() === $mapsFolder->getId() ) { - try { - $folder->delete(); - } catch (Exception $e) { - return 1; - } - } else { + $folders = $userFolder->getById($id); + $folder = array_shift($folders); + if ($userFolder->nodeExists('/Maps')) { + $mapsFolder = $userFolder->get('/Maps'); + if ($folder->getParent()->getId() === $mapsFolder->getId()) { + try { + $folder->delete(); + } catch (Exception $e) { + return 1; + } + } else { try { $file = $folder->get('.index.maps'); $file->delete(); @@ -223,14 +209,14 @@ public function deleteMyMap($id, $userId) { return 1; } } - } - try { - $file=$folder->get(".index.maps"); - $file->delete(); - } catch (NotFoundException $e) { - return 1; - } - return 0; - } + } + try { + $file = $folder->get('.index.maps'); + $file->delete(); + } catch (NotFoundException $e) { + return 1; + } + return 0; + } } diff --git a/lib/Service/PhotofilesService.php b/lib/Service/PhotofilesService.php index 7c1b7cde3..621a9c3f4 100644 --- a/lib/Service/PhotofilesService.php +++ b/lib/Service/PhotofilesService.php @@ -12,151 +12,145 @@ namespace OCA\Maps\Service; -use lsolesen\pel\PelEntryTime; +use OCA\Maps\BackgroundJob\AddPhotoJob; +use OCA\Maps\BackgroundJob\UpdatePhotoByFileJob; +use OCA\Maps\DB\Geophoto; +use OCA\Maps\DB\GeophotoMapper; use OCA\Maps\Helper\ExifDataInvalidException; use OCA\Maps\Helper\ExifDataNoLocationException; use OCA\Maps\Helper\ExifGeoData; use OCP\AppFramework\Db\DoesNotExistException; +use OCP\BackgroundJob\IJobList; use OCP\Files\FileInfo; -use OCP\ICacheFactory; -use OCP\IL10N; -use OCP\Files\IRootFolder; -use OCP\Files\Storage\IStorage; use OCP\Files\Folder; +use OCP\Files\IRootFolder; use OCP\Files\Node; + +use OCP\ICacheFactory; +use OCP\IL10N; use OCP\ILogger; use OCP\Share\IManager; -use OCP\Files\Mount\IMountPoint; -use \OCP\BackgroundJob\IJobList; - -use OCA\Maps\DB\Geophoto; -use OCA\Maps\DB\GeophotoMapper; -use OCA\Maps\BackgroundJob\AddPhotoJob; -use OCA\Maps\BackgroundJob\UpdatePhotoByFileJob; require_once __DIR__ . '/../../vendor/autoload.php'; use lsolesen\pel\PelDataWindow; -use lsolesen\pel\PelException; -use lsolesen\pel\PelJpeg; -use lsolesen\pel\PelExif; -use lsolesen\pel\PelTiff; -use lsolesen\pel\PelTag; use lsolesen\pel\PelEntryAscii; use lsolesen\pel\PelEntryRational; +use lsolesen\pel\PelExif; use lsolesen\pel\PelIfd; -use lsolesen\pel\Pel; +use lsolesen\pel\PelJpeg; +use lsolesen\pel\PelTag; +use lsolesen\pel\PelTiff; class PhotofilesService { - const PHOTO_MIME_TYPES = ['image/jpeg', 'image/tiff']; + public const PHOTO_MIME_TYPES = ['image/jpeg', 'image/tiff']; - private $l10n; - private $root; - private $photoMapper; - private $shareManager; - private $logger; - private $jobList; + private $l10n; + private $root; + private $photoMapper; + private $shareManager; + private $logger; + private $jobList; private ICacheFactory $cacheFactory; private \OCP\ICache $photosCache; private \OCP\ICache $backgroundJobCache; - public function __construct (ILogger $logger, - ICacheFactory $cacheFactory, - IRootFolder $root, - IL10N $l10n, - GeophotoMapper $photoMapper, - IManager $shareManager, - IJobList $jobList) { - $this->root = $root; - $this->l10n = $l10n; - $this->photoMapper = $photoMapper; - $this->shareManager = $shareManager; - $this->logger = $logger; - $this->jobList = $jobList; + public function __construct(ILogger $logger, + ICacheFactory $cacheFactory, + IRootFolder $root, + IL10N $l10n, + GeophotoMapper $photoMapper, + IManager $shareManager, + IJobList $jobList) { + $this->root = $root; + $this->l10n = $l10n; + $this->photoMapper = $photoMapper; + $this->shareManager = $shareManager; + $this->logger = $logger; + $this->jobList = $jobList; $this->cacheFactory = $cacheFactory; $this->photosCache = $this->cacheFactory->createDistributed('maps:photos'); $this->backgroundJobCache = $this->cacheFactory->createDistributed('maps:background-jobs'); - } + } - public function rescan($userId, $inBackground=true) { + public function rescan($userId, $inBackground = true) { $this->photosCache->clear($userId); - $userFolder = $this->root->getUserFolder($userId); - $photos = $this->gatherPhotoFiles($userFolder, true); - $this->photoMapper->deleteAll($userId); - foreach ($photos as $photo) { + $userFolder = $this->root->getUserFolder($userId); + $photos = $this->gatherPhotoFiles($userFolder, true); + $this->photoMapper->deleteAll($userId); + foreach ($photos as $photo) { if ($inBackground) { $this->addPhoto($photo, $userId); } else { $this->addPhotoNow($photo, $userId); } - yield $photo->getPath(); - } - } - - // add the file for its owner and users that have access - // check if it's already in DB before adding - public function addByFile(Node $file) { - $ownerId = $file->getOwner()->getUID(); - if ($this->isPhoto($file)) { - $this->addPhoto($file, $ownerId); - // is the file accessible to other users ? - $accesses = $this->shareManager->getAccessList($file); - foreach ($accesses['users'] as $uid) { - if ($uid !== $ownerId) { - $this->addPhoto($file, $uid); - } - } - return true; - } - else { - return false; - } - } - - public function addByFileIdUserId($fileId, $userId) { - $userFolder = $this->root->getUserFolder($userId); - $files = $userFolder->getById($fileId); - if (empty($files)) { - return; - } - $file = array_shift($files); - if ($file !== null and $this->isPhoto($file)) { - $this->addPhoto($file, $userId); - } - } - - public function addByFolderIdUserId($folderId, $userId) { - $folders = $this->root->getById($folderId); + yield $photo->getPath(); + } + } + + // add the file for its owner and users that have access + // check if it's already in DB before adding + public function addByFile(Node $file) { + $ownerId = $file->getOwner()->getUID(); + if ($this->isPhoto($file)) { + $this->addPhoto($file, $ownerId); + // is the file accessible to other users ? + $accesses = $this->shareManager->getAccessList($file); + foreach ($accesses['users'] as $uid) { + if ($uid !== $ownerId) { + $this->addPhoto($file, $uid); + } + } + return true; + } else { + return false; + } + } + + public function addByFileIdUserId($fileId, $userId) { + $userFolder = $this->root->getUserFolder($userId); + $files = $userFolder->getById($fileId); + if (empty($files)) { + return; + } + $file = array_shift($files); + if ($file !== null and $this->isPhoto($file)) { + $this->addPhoto($file, $userId); + } + } + + public function addByFolderIdUserId($folderId, $userId) { + $folders = $this->root->getById($folderId); if (empty($folders)) { return; } $folder = array_shift($folders); - if ($folder !== null) { - $photos = $this->gatherPhotoFiles($folder, true); - foreach($photos as $photo) { - $this->addPhoto($photo, $userId); - } - } - } - - // add all photos of a folder taking care of shared accesses - public function addByFolder($folder) { - $photos = $this->gatherPhotoFiles($folder, true); - foreach($photos as $photo) { - $this->addByFile($photo); - } - } - - public function updateByFile(Node $file) { - $this->jobList->add(UpdatePhotoByFileJob::class, ['fileId' => $file->getId(), 'userId' => $file->getOwner()->getUID()]); - } - - public function updateByFileNow(Node $file) { - if ($this->isPhoto($file)) { - $exif = $this->getExif($file); - if (!is_null($exif)) { - $ownerId = $file->getOwner()->getUID(); - // in case there is no entry for this file yet (normally there is because non-localized photos are added) + if ($folder !== null) { + $photos = $this->gatherPhotoFiles($folder, true); + foreach ($photos as $photo) { + $this->addPhoto($photo, $userId); + } + } + } + + // add all photos of a folder taking care of shared accesses + public function addByFolder($folder) { + $photos = $this->gatherPhotoFiles($folder, true); + foreach ($photos as $photo) { + $this->addByFile($photo); + } + } + + public function updateByFile(Node $file) { + $this->jobList->add(UpdatePhotoByFileJob::class, ['fileId' => $file->getId(), 'userId' => $file->getOwner()->getUID()]); + } + + public function updateByFileNow(Node $file) { + if ($this->isPhoto($file)) { + $exif = $this->getExif($file); + if (!is_null($exif)) { + $ownerId = $file->getOwner()->getUID(); + // in case there is no entry for this file yet (normally there is because non-localized photos are added) try { $this->photoMapper->findByFileIdUserId($file->getId(), $ownerId); $this->updatePhoto($file, $exif); @@ -164,69 +158,69 @@ public function updateByFileNow(Node $file) { } catch (DoesNotExistException $exception) { $this->insertPhoto($file, $ownerId, $exif); } - } - } - } - - public function deleteByFile(Node $file) { - $this->photoMapper->deleteByFileId($file->getId()); - } - - // delete photo only if it's not accessible to user anymore - // it might have been shared multiple times by different users - public function deleteByFileIdUserId($fileId, $userId) { - $userFolder = $this->root->getUserFolder($userId); - $files = $userFolder->getById($fileId); - if (!is_array($files) or count($files) === 0) { - $this->photoMapper->deleteByFileIdUserId($fileId, $userId); + } + } + } + + public function deleteByFile(Node $file) { + $this->photoMapper->deleteByFileId($file->getId()); + } + + // delete photo only if it's not accessible to user anymore + // it might have been shared multiple times by different users + public function deleteByFileIdUserId($fileId, $userId) { + $userFolder = $this->root->getUserFolder($userId); + $files = $userFolder->getById($fileId); + if (!is_array($files) or count($files) === 0) { + $this->photoMapper->deleteByFileIdUserId($fileId, $userId); $this->photosCache->clear($userId); - } - } - - - public function deleteByFolder(Node $folder) { - $photos = $this->gatherPhotoFiles($folder, true); - foreach ($photos as $photo) { - $this->photoMapper->deleteByFileId($photo->getId()); - } - } - - // delete folder photos only if it's not accessible to user anymore - public function deleteByFolderIdUserId($folderId, $userId) { - $userFolder = $this->root->getUserFolder($userId); - $folders = $userFolder->getById($folderId); - if (is_array($folders) and count($folders) === 1) { - $folder = array_shift($folders); - $photos = $this->gatherPhotoFiles($folder, true); - foreach($photos as $photo) { - $this->photoMapper->deleteByFileIdUserId($photo->getId(), $userId); - } + } + } + + + public function deleteByFolder(Node $folder) { + $photos = $this->gatherPhotoFiles($folder, true); + foreach ($photos as $photo) { + $this->photoMapper->deleteByFileId($photo->getId()); + } + } + + // delete folder photos only if it's not accessible to user anymore + public function deleteByFolderIdUserId($folderId, $userId) { + $userFolder = $this->root->getUserFolder($userId); + $folders = $userFolder->getById($folderId); + if (is_array($folders) and count($folders) === 1) { + $folder = array_shift($folders); + $photos = $this->gatherPhotoFiles($folder, true); + foreach ($photos as $photo) { + $this->photoMapper->deleteByFileIdUserId($photo->getId(), $userId); + } $this->photosCache->clear($userId); - } - } + } + } /** * @param $userId * @return array */ public function getBackgroundJobStatus($userId): array { - $add_counter = 0; - $addJobsRunning = False; + $add_counter = 0; + $addJobsRunning = false; - foreach ($this->jobList->getJobsIterator(AddPhotoJob::class, Null, 0) as $job) { + foreach ($this->jobList->getJobsIterator(AddPhotoJob::class, null, 0) as $job) { if ($job->getArgument()['userId'] === $userId) { $add_counter += 1; } - $addJobsRunning = True; + $addJobsRunning = true; } $update_counter = 0; - $updateJobsRunning = False; + $updateJobsRunning = false; - foreach ($this->jobList->getJobsIterator(UpdatePhotoByFileJob::class, Null, 0) as $job) { + foreach ($this->jobList->getJobsIterator(UpdatePhotoByFileJob::class, null, 0) as $job) { if ($job->getArgument()['userId'] === $userId) { $update_counter += 1; } - $updateJobsRunning = True; + $updateJobsRunning = true; } $recentlyAdded = $this->backgroundJobCache->get('recentlyAdded:'.$userId) ?? 0; $recentlyUpdated = $this->backgroundJobCache->get('$recentlyUpdated:'.$userId) ?? 0; @@ -240,312 +234,315 @@ public function getBackgroundJobStatus($userId): array { ]; } - public function setPhotosFilesCoords($userId, $paths, $lats, $lngs, $directory) { - if ($directory) { - return $this->setDirectoriesCoords($userId, $paths, $lats, $lngs); - } - else { - return $this->setFilesCoords($userId, $paths, $lats, $lngs); - } - } - - private function setDirectoriesCoords($userId, $paths, $lats, $lngs) { - $lat = $lats[0] ?? 0; - $lng = $lngs[0] ?? 0; - $userFolder = $this->root->getUserFolder($userId); - $done = []; - foreach ($paths as $dirPath) { - $cleanDirPath = str_replace(array('../', '..\\'), '', $dirPath); - if ($userFolder->nodeExists($cleanDirPath)) { - $dir = $userFolder->get($cleanDirPath); - if ($dir->getType() === FileInfo::TYPE_FOLDER) { - $nodes = $dir->getDirectoryListing(); - foreach($nodes as $node) { - if ($this->isPhoto($node) && $node->isUpdateable()) { - $photo = $this->photoMapper->findByFileIdUserId($node->getId(), $userId); - $done[] = [ - 'path' => preg_replace('/^files/', '', $node->getInternalPath()), - 'lat' => $lat, - 'lng' => $lng, - 'oldLat' => $photo ? $photo->getLat() : null, - 'oldLng' => $photo ? $photo->getLng() : null, - ]; - $this->setExifCoords($node, $lat, $lng); - $this->updateByFileNow($node); - } - } - } - } - } - return $done; - } - - private function setFilesCoords($userId, $paths, $lats, $lngs) { - $userFolder = $this->root->getUserFolder($userId); - $done = []; - - foreach ($paths as $i => $path) { - $cleanpath = str_replace(array('../', '..\\'), '', $path); - if ($userFolder->nodeExists($cleanpath)) { - $file = $userFolder->get($cleanpath); - if ($this->isPhoto($file) && $file->isUpdateable()) { - $lat = (count($lats) > $i) ? $lats[$i] : $lats[0]; - $lng = (count($lngs) > $i) ? $lngs[$i] : $lngs[0]; - $photo = $this->photoMapper->findByFileIdUserId($file->getId(), $userId); - $done[] = [ - 'path' => preg_replace('/^files/', '', $file->getInternalPath()), - 'lat' => $lat, - 'lng' => $lng, - 'oldLat' => $photo ? $photo->getLat() : null, - 'oldLng' => $photo ? $photo->getLng() : null, - ]; - $this->setExifCoords($file, $lat, $lng); - $this->updateByFileNow($file); - } - } - } - return $done; - } - - public function resetPhotosFilesCoords($userId, $paths) { - $userFolder = $this->root->getUserFolder($userId); - $done = []; - - foreach ($paths as $i => $path) { - $cleanpath = str_replace(array('../', '..\\'), '', $path); - if ($userFolder->nodeExists($cleanpath)) { - $file = $userFolder->get($cleanpath); - if ($this->isPhoto($file) && $file->isUpdateable()) { - $photo = $this->photoMapper->findByFileIdUserId($file->getId(), $userId); - $done[] = [ - 'path' => preg_replace('/^files/', '', $file->getInternalPath()), - 'lat' => null, - 'lng' => null, - 'oldLat' => $photo ? $photo->getLat() : null, - 'oldLng' => $photo ? $photo->getLng() : null, - ]; - $this->resetExifCoords($file); - $this->photoMapper->updateByFileId($file->getId(), null, null); - } - } - } - return $done; - } - - // avoid adding photo if it already exists in the DB - private function addPhoto($photo, $userId) { - $this->jobList->add(AddPhotoJob::class, ['photoId' => $photo->getId(), 'userId' => $userId]); - } - - public function addPhotoNow($photo, $userId) { - $exif = $this->getExif($photo); - if (!is_null($exif)) { - // filehooks are triggered several times (2 times for file creation) - // so we need to be sure it's not inserted several times - // by checking if it already exists in DB - // OR by using file_id in primary key - try { + public function setPhotosFilesCoords($userId, $paths, $lats, $lngs, $directory) { + if ($directory) { + return $this->setDirectoriesCoords($userId, $paths, $lats, $lngs); + } else { + return $this->setFilesCoords($userId, $paths, $lats, $lngs); + } + } + + private function setDirectoriesCoords($userId, $paths, $lats, $lngs) { + $lat = $lats[0] ?? 0; + $lng = $lngs[0] ?? 0; + $userFolder = $this->root->getUserFolder($userId); + $done = []; + foreach ($paths as $dirPath) { + $cleanDirPath = str_replace(['../', '..\\'], '', $dirPath); + if ($userFolder->nodeExists($cleanDirPath)) { + $dir = $userFolder->get($cleanDirPath); + if ($dir->getType() === FileInfo::TYPE_FOLDER) { + $nodes = $dir->getDirectoryListing(); + foreach ($nodes as $node) { + if ($this->isPhoto($node) && $node->isUpdateable()) { + $photo = $this->photoMapper->findByFileIdUserId($node->getId(), $userId); + $done[] = [ + 'path' => preg_replace('/^files/', '', $node->getInternalPath()), + 'lat' => $lat, + 'lng' => $lng, + 'oldLat' => $photo ? $photo->getLat() : null, + 'oldLng' => $photo ? $photo->getLng() : null, + ]; + $this->setExifCoords($node, $lat, $lng); + $this->updateByFileNow($node); + } + } + } + } + } + return $done; + } + + private function setFilesCoords($userId, $paths, $lats, $lngs) { + $userFolder = $this->root->getUserFolder($userId); + $done = []; + + foreach ($paths as $i => $path) { + $cleanpath = str_replace(['../', '..\\'], '', $path); + if ($userFolder->nodeExists($cleanpath)) { + $file = $userFolder->get($cleanpath); + if ($this->isPhoto($file) && $file->isUpdateable()) { + $lat = (count($lats) > $i) ? $lats[$i] : $lats[0]; + $lng = (count($lngs) > $i) ? $lngs[$i] : $lngs[0]; + $photo = $this->photoMapper->findByFileIdUserId($file->getId(), $userId); + $done[] = [ + 'path' => preg_replace('/^files/', '', $file->getInternalPath()), + 'lat' => $lat, + 'lng' => $lng, + 'oldLat' => $photo ? $photo->getLat() : null, + 'oldLng' => $photo ? $photo->getLng() : null, + ]; + $this->setExifCoords($file, $lat, $lng); + $this->updateByFileNow($file); + } + } + } + return $done; + } + + public function resetPhotosFilesCoords($userId, $paths) { + $userFolder = $this->root->getUserFolder($userId); + $done = []; + + foreach ($paths as $i => $path) { + $cleanpath = str_replace(['../', '..\\'], '', $path); + if ($userFolder->nodeExists($cleanpath)) { + $file = $userFolder->get($cleanpath); + if ($this->isPhoto($file) && $file->isUpdateable()) { + $photo = $this->photoMapper->findByFileIdUserId($file->getId(), $userId); + $done[] = [ + 'path' => preg_replace('/^files/', '', $file->getInternalPath()), + 'lat' => null, + 'lng' => null, + 'oldLat' => $photo ? $photo->getLat() : null, + 'oldLng' => $photo ? $photo->getLng() : null, + ]; + $this->resetExifCoords($file); + $this->photoMapper->updateByFileId($file->getId(), null, null); + } + } + } + return $done; + } + + // avoid adding photo if it already exists in the DB + private function addPhoto($photo, $userId) { + $this->jobList->add(AddPhotoJob::class, ['photoId' => $photo->getId(), 'userId' => $userId]); + } + + public function addPhotoNow($photo, $userId) { + $exif = $this->getExif($photo); + if (!is_null($exif)) { + // filehooks are triggered several times (2 times for file creation) + // so we need to be sure it's not inserted several times + // by checking if it already exists in DB + // OR by using file_id in primary key + try { $this->photoMapper->findByFileIdUserId($photo->getId(), $userId); } catch (DoesNotExistException $exception) { - $this->insertPhoto($photo, $userId, $exif); - } + $this->insertPhoto($photo, $userId, $exif); + } $this->photosCache->clear($userId); - } - } - - - private function insertPhoto($photo, $userId, $exif) { - $photoEntity = new Geophoto(); - $photoEntity->setFileId($photo->getId()); - $photoEntity->setLat( - is_numeric($exif->lat)&&!is_nan($exif->lat) ? $exif->lat : null - ); - $photoEntity->setLng( - is_numeric($exif->lng)&&!is_nan($exif->lng) ? $exif->lng : null - ); - $photoEntity->setUserId($userId); - // alternative should be file creation date - $photoEntity->setDateTaken($exif->dateTaken ?? $photo->getMTime()); - $this->photoMapper->insert($photoEntity); + } + } + + + private function insertPhoto($photo, $userId, $exif) { + $photoEntity = new Geophoto(); + $photoEntity->setFileId($photo->getId()); + $photoEntity->setLat( + is_numeric($exif->lat) && !is_nan($exif->lat) ? $exif->lat : null + ); + $photoEntity->setLng( + is_numeric($exif->lng) && !is_nan($exif->lng) ? $exif->lng : null + ); + $photoEntity->setUserId($userId); + // alternative should be file creation date + $photoEntity->setDateTaken($exif->dateTaken ?? $photo->getMTime()); + $this->photoMapper->insert($photoEntity); $this->photosCache->clear($userId); - } - - private function updatePhoto($file, $exif) { - $lat = is_numeric($exif->lat)&&!is_nan($exif->lat) ? $exif->lat : null; - $lng = is_numeric($exif->lng)&&!is_nan($exif->lng) ? $exif->lng : null; - $this->photoMapper->updateByFileId($file->getId(), $lat, $lng); - } - - private function normalizePath($node) { - return str_replace("files","", $node->getInternalPath()); - } - - public function getPhotosByFolder($userId, $path) { - $userFolder = $this->root->getUserFolder($userId); - $folder = $userFolder->get($path); - return $this->getPhotosListForFolder($folder); - } - - private function getPhotosListForFolder($folder) { - $FilesList = $this->gatherPhotoFiles($folder, false); - $notes = []; - foreach($FilesList as $File) { - $file_object = new \stdClass(); - $file_object->fileId = $File->getId(); - $file_object->path = $this->normalizePath($File); - $notes[] = $file_object; - } - return $notes; - } - - private function gatherPhotoFiles ($folder, $recursive) { - $notes = []; - $nodes = $folder->getDirectoryListing(); - foreach ($nodes as $node) { - if ($node->getType() === FileInfo::TYPE_FOLDER AND $recursive) { - // we don't explore external storages for which previews are disabled - if ($node->isMounted()) { - $options = $node->getMountPoint()->getOptions(); - if (!(isset($options['previews']) && $options['previews'])) { - continue; - } - } - try { - $notes = array_merge($notes, $this->gatherPhotoFiles($node, $recursive)); - } catch (\OCP\Files\StorageNotAvailableException | \Exception $e) { - $msg = "WARNING: Could not access " . $node->getName(); - echo($msg . "\n"); - $this->logger->error($msg); - } - continue; - } - if ($this->isPhoto($node)) { - $notes[] = $node; - } - } - return $notes; - } - - private function isPhoto($file) { - if ($file->getType() !== \OCP\Files\FileInfo::TYPE_FILE) return false; - if (!in_array($file->getMimetype(), self::PHOTO_MIME_TYPES)) return false; - return true; - } - - /** - * Get exif geo Data object - * returns with null in any validation or Critical errors - * - * @param $file - * @return ExifGeoData|null - */ - private function getExif($file) : ?ExifGeoData { - $path = $file->getStorage()->getLocalFile($file->getInternalPath()); - try{ - $exif_geo_data = ExifGeoData::get($path); - $exif_geo_data->validate(true); - }catch(ExifDataInvalidException $e){ - $exif_geo_data = null; - $this->logger->notice($e->getMessage(), ['code'=>$e->getCode(),'path'=>$path]); - }catch(ExifDataNoLocationException $e){ - $this->logger->notice($e->getMessage(), ['code'=>$e->getCode(),'path'=>$path]); - }catch(\Throwable $f){ - $exif_geo_data = null; - $this->logger->error($f->getMessage(), ['code'=>$f->getCode(),'path'=>$path]); - } - return $exif_geo_data; - } - - private function resetExifCoords($file) { - $data = new PelDataWindow($file->getContent()); - $pelJpeg = new PelJpeg($data); - - $pelExif = $pelJpeg->getExif(); - if ($pelExif === null) { - $pelExif = new PelExif(); - $pelJpeg->setExif($pelExif); - } - - $pelTiff = $pelExif->getTiff(); - if ($pelTiff === null) { - $pelTiff = new PelTiff(); - $pelExif->setTiff($pelTiff); - } - - $pelIfd0 = $pelTiff->getIfd(); - if ($pelIfd0 === null) { - $pelIfd0 = new PelIfd(PelIfd::IFD0); - $pelTiff->setIfd($pelIfd0); - } - - $pelSubIfdGps = new PelIfd(PelIfd::GPS); - $pelIfd0->addSubIfd($pelSubIfdGps); - - $file->putContent($pelJpeg->getBytes()); - } - - private function setExifCoords($file, $lat, $lng) { - $data = new PelDataWindow($file->getContent()); - $pelJpeg = new PelJpeg($data); - - $pelExif = $pelJpeg->getExif(); - if ($pelExif === null) { - $pelExif = new PelExif(); - $pelJpeg->setExif($pelExif); - } - - $pelTiff = $pelExif->getTiff(); - if ($pelTiff === null) { - $pelTiff = new PelTiff(); - $pelExif->setTiff($pelTiff); - } - - $pelIfd0 = $pelTiff->getIfd(); - if ($pelIfd0 === null) { - $pelIfd0 = new PelIfd(PelIfd::IFD0); - $pelTiff->setIfd($pelIfd0); - } - - $pelSubIfdGps = new PelIfd(PelIfd::GPS); - $pelIfd0->addSubIfd($pelSubIfdGps); - - $this->setGeolocation($pelSubIfdGps, $lat, $lng); - - $file->putContent($pelJpeg->getBytes()); - } - - private function setGeolocation($pelSubIfdGps, $latitudeDegreeDecimal, $longitudeDegreeDecimal) { - $latitudeRef = ($latitudeDegreeDecimal >= 0) ? 'N' : 'S'; - $latitudeDegreeMinuteSecond - = $this->degreeDecimalToDegreeMinuteSecond(abs($latitudeDegreeDecimal)); - $longitudeRef= ($longitudeDegreeDecimal >= 0) ? 'E' : 'W'; - $longitudeDegreeMinuteSecond - = $this->degreeDecimalToDegreeMinuteSecond(abs($longitudeDegreeDecimal)); - - $pelSubIfdGps->addEntry(new PelEntryAscii( - PelTag::GPS_LATITUDE_REF, $latitudeRef)); - $pelSubIfdGps->addEntry(new PelEntryRational( - PelTag::GPS_LATITUDE, - array($latitudeDegreeMinuteSecond['degree'], 1), - array($latitudeDegreeMinuteSecond['minute'], 1), - array(round($latitudeDegreeMinuteSecond['second'] * 1000), 1000))); - $pelSubIfdGps->addEntry(new PelEntryAscii( - PelTag::GPS_LONGITUDE_REF, $longitudeRef)); - $pelSubIfdGps->addEntry(new PelEntryRational( - PelTag::GPS_LONGITUDE, - array($longitudeDegreeMinuteSecond['degree'], 1), - array($longitudeDegreeMinuteSecond['minute'], 1), - array(round($longitudeDegreeMinuteSecond['second'] * 1000), 1000))); - } - - private function degreeDecimalToDegreeMinuteSecond($degreeDecimal) { - $degree = floor($degreeDecimal); - $remainder = $degreeDecimal - $degree; - $minute = floor($remainder * 60); - $remainder = ($remainder * 60) - $minute; - $second = $remainder * 60; - return array('degree' => $degree, 'minute' => $minute, 'second' => $second); - } + } + + private function updatePhoto($file, $exif) { + $lat = is_numeric($exif->lat) && !is_nan($exif->lat) ? $exif->lat : null; + $lng = is_numeric($exif->lng) && !is_nan($exif->lng) ? $exif->lng : null; + $this->photoMapper->updateByFileId($file->getId(), $lat, $lng); + } + + private function normalizePath($node) { + return str_replace('files', '', $node->getInternalPath()); + } + + public function getPhotosByFolder($userId, $path) { + $userFolder = $this->root->getUserFolder($userId); + $folder = $userFolder->get($path); + return $this->getPhotosListForFolder($folder); + } + + private function getPhotosListForFolder($folder) { + $FilesList = $this->gatherPhotoFiles($folder, false); + $notes = []; + foreach ($FilesList as $File) { + $file_object = new \stdClass(); + $file_object->fileId = $File->getId(); + $file_object->path = $this->normalizePath($File); + $notes[] = $file_object; + } + return $notes; + } + + private function gatherPhotoFiles($folder, $recursive) { + $notes = []; + $nodes = $folder->getDirectoryListing(); + foreach ($nodes as $node) { + if ($node->getType() === FileInfo::TYPE_FOLDER and $recursive) { + // we don't explore external storages for which previews are disabled + if ($node->isMounted()) { + $options = $node->getMountPoint()->getOptions(); + if (!(isset($options['previews']) && $options['previews'])) { + continue; + } + } + try { + $notes = array_merge($notes, $this->gatherPhotoFiles($node, $recursive)); + } catch (\OCP\Files\StorageNotAvailableException|\Exception $e) { + $msg = 'WARNING: Could not access ' . $node->getName(); + echo($msg . "\n"); + $this->logger->error($msg); + } + continue; + } + if ($this->isPhoto($node)) { + $notes[] = $node; + } + } + return $notes; + } + + private function isPhoto($file) { + if ($file->getType() !== \OCP\Files\FileInfo::TYPE_FILE) { + return false; + } + if (!in_array($file->getMimetype(), self::PHOTO_MIME_TYPES)) { + return false; + } + return true; + } + + /** + * Get exif geo Data object + * returns with null in any validation or Critical errors + * + * @param $file + * @return ExifGeoData|null + */ + private function getExif($file) : ?ExifGeoData { + $path = $file->getStorage()->getLocalFile($file->getInternalPath()); + try { + $exif_geo_data = ExifGeoData::get($path); + $exif_geo_data->validate(true); + } catch (ExifDataInvalidException $e) { + $exif_geo_data = null; + $this->logger->notice($e->getMessage(), ['code' => $e->getCode(),'path' => $path]); + } catch (ExifDataNoLocationException $e) { + $this->logger->notice($e->getMessage(), ['code' => $e->getCode(),'path' => $path]); + } catch (\Throwable $f) { + $exif_geo_data = null; + $this->logger->error($f->getMessage(), ['code' => $f->getCode(),'path' => $path]); + } + return $exif_geo_data; + } + + private function resetExifCoords($file) { + $data = new PelDataWindow($file->getContent()); + $pelJpeg = new PelJpeg($data); + + $pelExif = $pelJpeg->getExif(); + if ($pelExif === null) { + $pelExif = new PelExif(); + $pelJpeg->setExif($pelExif); + } + + $pelTiff = $pelExif->getTiff(); + if ($pelTiff === null) { + $pelTiff = new PelTiff(); + $pelExif->setTiff($pelTiff); + } + + $pelIfd0 = $pelTiff->getIfd(); + if ($pelIfd0 === null) { + $pelIfd0 = new PelIfd(PelIfd::IFD0); + $pelTiff->setIfd($pelIfd0); + } + + $pelSubIfdGps = new PelIfd(PelIfd::GPS); + $pelIfd0->addSubIfd($pelSubIfdGps); + + $file->putContent($pelJpeg->getBytes()); + } + + private function setExifCoords($file, $lat, $lng) { + $data = new PelDataWindow($file->getContent()); + $pelJpeg = new PelJpeg($data); + + $pelExif = $pelJpeg->getExif(); + if ($pelExif === null) { + $pelExif = new PelExif(); + $pelJpeg->setExif($pelExif); + } + + $pelTiff = $pelExif->getTiff(); + if ($pelTiff === null) { + $pelTiff = new PelTiff(); + $pelExif->setTiff($pelTiff); + } + + $pelIfd0 = $pelTiff->getIfd(); + if ($pelIfd0 === null) { + $pelIfd0 = new PelIfd(PelIfd::IFD0); + $pelTiff->setIfd($pelIfd0); + } + + $pelSubIfdGps = new PelIfd(PelIfd::GPS); + $pelIfd0->addSubIfd($pelSubIfdGps); + + $this->setGeolocation($pelSubIfdGps, $lat, $lng); + + $file->putContent($pelJpeg->getBytes()); + } + + private function setGeolocation($pelSubIfdGps, $latitudeDegreeDecimal, $longitudeDegreeDecimal) { + $latitudeRef = ($latitudeDegreeDecimal >= 0) ? 'N' : 'S'; + $latitudeDegreeMinuteSecond + = $this->degreeDecimalToDegreeMinuteSecond(abs($latitudeDegreeDecimal)); + $longitudeRef = ($longitudeDegreeDecimal >= 0) ? 'E' : 'W'; + $longitudeDegreeMinuteSecond + = $this->degreeDecimalToDegreeMinuteSecond(abs($longitudeDegreeDecimal)); + + $pelSubIfdGps->addEntry(new PelEntryAscii( + PelTag::GPS_LATITUDE_REF, $latitudeRef)); + $pelSubIfdGps->addEntry(new PelEntryRational( + PelTag::GPS_LATITUDE, + [$latitudeDegreeMinuteSecond['degree'], 1], + [$latitudeDegreeMinuteSecond['minute'], 1], + [round($latitudeDegreeMinuteSecond['second'] * 1000), 1000])); + $pelSubIfdGps->addEntry(new PelEntryAscii( + PelTag::GPS_LONGITUDE_REF, $longitudeRef)); + $pelSubIfdGps->addEntry(new PelEntryRational( + PelTag::GPS_LONGITUDE, + [$longitudeDegreeMinuteSecond['degree'], 1], + [$longitudeDegreeMinuteSecond['minute'], 1], + [round($longitudeDegreeMinuteSecond['second'] * 1000), 1000])); + } + + private function degreeDecimalToDegreeMinuteSecond($degreeDecimal) { + $degree = floor($degreeDecimal); + $remainder = $degreeDecimal - $degree; + $minute = floor($remainder * 60); + $remainder = ($remainder * 60) - $minute; + $second = $remainder * 60; + return ['degree' => $degree, 'minute' => $minute, 'second' => $second]; + } } diff --git a/lib/Service/TracksService.php b/lib/Service/TracksService.php index 3a08eb3df..0e85fa6d5 100644 --- a/lib/Service/TracksService.php +++ b/lib/Service/TracksService.php @@ -15,187 +15,190 @@ use OC\Files\Search\SearchBinaryOperator; use OC\Files\Search\SearchComparison; use OC\Files\Search\SearchQuery; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\Files\FileInfo; +use OCP\Files\Folder; +use OCP\Files\IRootFolder; +use OCP\Files\Node; use OCP\Files\Search\ISearchBinaryOperator; use OCP\Files\Search\ISearchComparison; +use OCP\IDBConnection; use OCP\IL10N; use OCP\ILogger; -use OCP\IDBConnection; -use OCP\DB\QueryBuilder\IQueryBuilder; -use OCP\Files\IRootFolder; -use OCP\Files\FileInfo; use OCP\Share\IManager; -use OCP\Files\Folder; -use OCP\Files\Node; class TracksService { - const TRACK_MIME_TYPES = ['application/gpx+xml']; - - private $l10n; - private $logger; - private $qb; - private $root; - private $shareManager; - - public function __construct (ILogger $logger, IL10N $l10n, IRootFolder $root, - IManager $shareManager, IDBConnection $dbconnection) { - $this->l10n = $l10n; - $this->logger = $logger; - $this->qb = $dbconnection->getQueryBuilder(); - $this->root = $root; - $this->shareManager = $shareManager; - } - - public function rescan($userId){ - $userFolder = $this->root->getUserFolder($userId); - $tracks = $this->gatherTrackFiles($userFolder, true); - $this->deleteAllTracksFromDB($userId); - foreach ($tracks as $track) { - $this->addTrackToDB($userId, $track->getId(), $track); - yield $track->getPath(); - } - } - - public function addByFile(Node $file) { - $userFolder = $this->root->getUserFolder($file->getOwner()->getUID()); - if ($this->isTrack($file)) { - $this->addTrackToDB($file->getOwner()->getUID(), $file->getId(), $file); - } - } - - // add the file for its owner and users that have access - // check if it's already in DB before adding - public function safeAddByFile(Node $file) { - $ownerId = $file->getOwner()->getUID(); - $userFolder = $this->root->getUserFolder($ownerId); - if ($this->isTrack($file)) { - $this->safeAddTrack($file, $ownerId); - // is the file accessible to other users ? - $accesses = $this->shareManager->getAccessList($file); - foreach ($accesses['users'] as $uid) { - if ($uid !== $ownerId) { - $this->safeAddTrack($file, $uid); - } - } - return true; - } - else { - return false; - } - } - - public function safeAddByFileIdUserId($fileId, $userId) { - $userFolder = $this->root->getUserFolder($userId); - $files = $userFolder->getById($fileId); + public const TRACK_MIME_TYPES = ['application/gpx+xml']; + + private $l10n; + private $logger; + private $qb; + private $root; + private $shareManager; + + public function __construct(ILogger $logger, IL10N $l10n, IRootFolder $root, + IManager $shareManager, IDBConnection $dbconnection) { + $this->l10n = $l10n; + $this->logger = $logger; + $this->qb = $dbconnection->getQueryBuilder(); + $this->root = $root; + $this->shareManager = $shareManager; + } + + public function rescan($userId) { + $userFolder = $this->root->getUserFolder($userId); + $tracks = $this->gatherTrackFiles($userFolder, true); + $this->deleteAllTracksFromDB($userId); + foreach ($tracks as $track) { + $this->addTrackToDB($userId, $track->getId(), $track); + yield $track->getPath(); + } + } + + public function addByFile(Node $file) { + $userFolder = $this->root->getUserFolder($file->getOwner()->getUID()); + if ($this->isTrack($file)) { + $this->addTrackToDB($file->getOwner()->getUID(), $file->getId(), $file); + } + } + + // add the file for its owner and users that have access + // check if it's already in DB before adding + public function safeAddByFile(Node $file) { + $ownerId = $file->getOwner()->getUID(); + $userFolder = $this->root->getUserFolder($ownerId); + if ($this->isTrack($file)) { + $this->safeAddTrack($file, $ownerId); + // is the file accessible to other users ? + $accesses = $this->shareManager->getAccessList($file); + foreach ($accesses['users'] as $uid) { + if ($uid !== $ownerId) { + $this->safeAddTrack($file, $uid); + } + } + return true; + } else { + return false; + } + } + + public function safeAddByFileIdUserId($fileId, $userId) { + $userFolder = $this->root->getUserFolder($userId); + $files = $userFolder->getById($fileId); if (empty($files)) { return; } $file = array_shift($files); - if ($file !== null and $this->isTrack($file)) { - $this->safeAddTrack($file, $userId); - } - } + if ($file !== null and $this->isTrack($file)) { + $this->safeAddTrack($file, $userId); + } + } - public function safeAddByFolderIdUserId($folderId, $userId) { - $folders = $this->root->getById($folderId); + public function safeAddByFolderIdUserId($folderId, $userId) { + $folders = $this->root->getById($folderId); if (empty($folders)) { return; } $folder = array_shift($folders); - if ($folder !== null) { - $tracks = $this->gatherTrackFiles($folder, true); - foreach ($tracks as $track) { - $this->safeAddTrack($track, $userId); - } - } - } - - // avoid adding track if it already exists in the DB - private function safeAddTrack($track, $userId) { - // filehooks are triggered several times (2 times for file creation) - // so we need to be sure it's not inserted several times - // by checking if it already exists in DB - // OR by using file_id in primary key - if ($this->getTrackByFileIDFromDB($track->getId(), $userId) === null) { - $this->addTrackToDB($userId, $track->getId(), $track); - } - } - - // add all tracks of a folder taking care of shared accesses - public function safeAddByFolder($folder) { - $tracks = $this->gatherTrackFiles($folder, true); - foreach($tracks as $track) { - $this->safeAddByFile($track); - } - } - - public function addByFolder(Node $folder) { - $tracks = $this->gatherTrackFiles($folder, true); - foreach($tracks as $track) { - $this->addTrackToDB($folder->getOwner()->getUID(), $track->getId(), $track); - } - } - - // delete track only if it's not accessible to user anymore - // it might have been shared multiple times by different users - public function safeDeleteByFileIdUserId($fileId, $userId) { - $userFolder = $this->root->getUserFolder($userId); - $files = $userFolder->getById($fileId); - if (!is_array($files) or count($files) === 0) { - $this->deleteByFileIdUserId($fileId, $userId); - } - } - - public function deleteByFile(Node $file) { - $this->deleteByFileId($file->getId()); - } - - public function deleteByFolder(Node $folder) { - $tracks = $this->gatherTrackFiles($folder, true); - foreach ($tracks as $track) { - $this->deleteByFileId($track->getId()); - } - } - - // delete folder tracks only if it's not accessible to user anymore - public function safeDeleteByFolderIdUserId($folderId, $userId) { - $userFolder = $this->root->getUserFolder($userId); - $folders = $userFolder->getById($folderId); - if (is_array($folders) and count($folders) === 1) { - $folder = array_shift($folders); - $tracks = $this->gatherTrackFiles($folder, true); - foreach($tracks as $track) { - $this->deleteByFileIdUserId($track->getId(), $userId); - } - } - } - - private function gatherTrackFiles($folder, $recursive) { - $notes = []; - $nodes = $folder->getDirectoryListing(); - foreach ($nodes as $node) { - if ($node->getType() === FileInfo::TYPE_FOLDER AND $recursive) { - try { - $notes = array_merge($notes, $this->gatherTrackFiles($node, $recursive)); - } catch (\OCP\Files\StorageNotAvailableException | \Exception $e) { - $msg = "WARNING: Could not access " . $node->getName(); - echo($msg . "\n"); - $this->logger->error($msg); - } - continue; - } - if ($this->isTrack($node)) { - $notes[] = $node; - } - } - return $notes; - } - - private function isTrack($file) { - if ($file->getType() !== \OCP\Files\FileInfo::TYPE_FILE) return false; - if (!in_array($file->getMimetype(), self::TRACK_MIME_TYPES)) return false; - return true; - } + if ($folder !== null) { + $tracks = $this->gatherTrackFiles($folder, true); + foreach ($tracks as $track) { + $this->safeAddTrack($track, $userId); + } + } + } + + // avoid adding track if it already exists in the DB + private function safeAddTrack($track, $userId) { + // filehooks are triggered several times (2 times for file creation) + // so we need to be sure it's not inserted several times + // by checking if it already exists in DB + // OR by using file_id in primary key + if ($this->getTrackByFileIDFromDB($track->getId(), $userId) === null) { + $this->addTrackToDB($userId, $track->getId(), $track); + } + } + + // add all tracks of a folder taking care of shared accesses + public function safeAddByFolder($folder) { + $tracks = $this->gatherTrackFiles($folder, true); + foreach ($tracks as $track) { + $this->safeAddByFile($track); + } + } + + public function addByFolder(Node $folder) { + $tracks = $this->gatherTrackFiles($folder, true); + foreach ($tracks as $track) { + $this->addTrackToDB($folder->getOwner()->getUID(), $track->getId(), $track); + } + } + + // delete track only if it's not accessible to user anymore + // it might have been shared multiple times by different users + public function safeDeleteByFileIdUserId($fileId, $userId) { + $userFolder = $this->root->getUserFolder($userId); + $files = $userFolder->getById($fileId); + if (!is_array($files) or count($files) === 0) { + $this->deleteByFileIdUserId($fileId, $userId); + } + } + + public function deleteByFile(Node $file) { + $this->deleteByFileId($file->getId()); + } + + public function deleteByFolder(Node $folder) { + $tracks = $this->gatherTrackFiles($folder, true); + foreach ($tracks as $track) { + $this->deleteByFileId($track->getId()); + } + } + + // delete folder tracks only if it's not accessible to user anymore + public function safeDeleteByFolderIdUserId($folderId, $userId) { + $userFolder = $this->root->getUserFolder($userId); + $folders = $userFolder->getById($folderId); + if (is_array($folders) and count($folders) === 1) { + $folder = array_shift($folders); + $tracks = $this->gatherTrackFiles($folder, true); + foreach ($tracks as $track) { + $this->deleteByFileIdUserId($track->getId(), $userId); + } + } + } + + private function gatherTrackFiles($folder, $recursive) { + $notes = []; + $nodes = $folder->getDirectoryListing(); + foreach ($nodes as $node) { + if ($node->getType() === FileInfo::TYPE_FOLDER and $recursive) { + try { + $notes = array_merge($notes, $this->gatherTrackFiles($node, $recursive)); + } catch (\OCP\Files\StorageNotAvailableException|\Exception $e) { + $msg = 'WARNING: Could not access ' . $node->getName(); + echo($msg . "\n"); + $this->logger->error($msg); + } + continue; + } + if ($this->isTrack($node)) { + $notes[] = $node; + } + } + return $notes; + } + + private function isTrack($file) { + if ($file->getType() !== \OCP\Files\FileInfo::TYPE_FILE) { + return false; + } + if (!in_array($file->getMimetype(), self::TRACK_MIME_TYPES)) { + return false; + } + return true; + } private function dbRowToTrack($row, $folder, $userFolder, $defaultMap, $ignoredPaths) { // avoid tracks that are not in "this map's" folder @@ -244,25 +247,25 @@ private function dbRowToTrack($row, $folder, $userFolder, $defaultMap, $ignoredP } - /** - * @param string $userId - */ - public function getTracksFromDB($userId, $folder=null, bool $respectNomediaAndNoimage=true, bool $hideTracksOnCustomMaps=false, bool $hideTracksInMapsFolder=true) { + /** + * @param string $userId + */ + public function getTracksFromDB($userId, $folder = null, bool $respectNomediaAndNoimage = true, bool $hideTracksOnCustomMaps = false, bool $hideTracksInMapsFolder = true) { $ignoredPaths = $respectNomediaAndNoimage ? $this->getIgnoredPaths($userId, $folder, $hideTracksOnCustomMaps) : []; if ($hideTracksInMapsFolder) { $ignoredPaths[] = '/Maps'; } $userFolder = $this->root->getUserFolder($userId); - $tracks = []; - $qb = $this->qb; - $qb->select('id', 'file_id', 'color', 'metadata', 'etag') - ->from('maps_tracks', 't') - ->where( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - $req = $qb->execute(); - - if (is_null($folder)) { + $tracks = []; + $qb = $this->qb; + $qb->select('id', 'file_id', 'color', 'metadata', 'etag') + ->from('maps_tracks', 't') + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + $req = $qb->execute(); + + if (is_null($folder)) { $folder = $userFolder; } $defaultMap = $folder->getId() === $userFolder->getId(); @@ -275,10 +278,10 @@ public function getTracksFromDB($userId, $folder=null, bool $respectNomediaAndNo } $tracks[] = $track; } - $req->closeCursor(); - $qb = $qb->resetQueryParts(); - return $tracks; - } + $req->closeCursor(); + $qb = $qb->resetQueryParts(); + return $tracks; + } /** * @param $userId @@ -288,7 +291,7 @@ public function getTracksFromDB($userId, $folder=null, bool $respectNomediaAndNo * @throws \OCP\Files\NotPermittedException * @throws \OC\User\NoUserException */ - private function getIgnoredPaths($userId, $folder=null, $hideImagesOnCustomMaps=true){ + private function getIgnoredPaths($userId, $folder = null, $hideImagesOnCustomMaps = true) { $ignoredPaths = []; $userFolder = $this->root->getUserFolder($userId); if (is_null($folder)) { @@ -302,38 +305,38 @@ private function getIgnoredPaths($userId, $folder=null, $hideImagesOnCustomMaps= if ($hideImagesOnCustomMaps) { $ignoreFileMimetypes[] = 'application/x-nextcloud-maps'; } - $func = function(string $i): SearchComparison { + $func = function (string $i): SearchComparison { return new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', $i); }; $excludedNodes = $folder->search(new SearchQuery( new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, array_map( - $func, - $ignoreFileMimetypes) - ), + $func, + $ignoreFileMimetypes) + ), 0, 0, [] )); - foreach($excludedNodes as $node) { + foreach ($excludedNodes as $node) { $ignoredPaths[] = $userFolder->getRelativePath($node->getParent()->getPath()); } return $ignoredPaths; } - public function getTrackFromDB($id, $userId=null) { - $track = null; - $qb = $this->qb; - $qb->select('id', 'file_id', 'color', 'metadata', 'etag') - ->from('maps_tracks', 't') - ->where( - $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) - ); - if ($userId !== null) { - $qb->andWhere( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - } - $req = $qb->execute(); + public function getTrackFromDB($id, $userId = null) { + $track = null; + $qb = $this->qb; + $qb->select('id', 'file_id', 'color', 'metadata', 'etag') + ->from('maps_tracks', 't') + ->where( + $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) + ); + if ($userId !== null) { + $qb->andWhere( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + } + $req = $qb->execute(); while ($row = $req->fetch()) { if ($userId !== '' and $userId !== null) { @@ -366,27 +369,27 @@ public function getTrackFromDB($id, $userId=null) { } break; } - $req->closeCursor(); - $qb = $qb->resetQueryParts(); - return $track; - } - - public function getTrackByFileIDFromDB($fileId, $userId=null) { - $track = null; - $qb = $this->qb; - $qb->select('id', 'file_id', 'color', 'metadata', 'etag') - ->from('maps_tracks', 't') - ->where( - $qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)) - ); - if ($userId !== null) { - $qb->andWhere( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - } - $req = $qb->execute(); - - while ($row = $req->fetch()) { + $req->closeCursor(); + $qb = $qb->resetQueryParts(); + return $track; + } + + public function getTrackByFileIDFromDB($fileId, $userId = null) { + $track = null; + $qb = $this->qb; + $qb->select('id', 'file_id', 'color', 'metadata', 'etag') + ->from('maps_tracks', 't') + ->where( + $qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)) + ); + if ($userId !== null) { + $qb->andWhere( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + } + $req = $qb->execute(); + + while ($row = $req->fetch()) { if ($userId !== '' and $userId !== null) { $userFolder = $this->root->getUserFolder($userId); $files = $userFolder->getById(intval($row['file_id'])); @@ -397,7 +400,7 @@ public function getTrackByFileIDFromDB($fileId, $userId=null) { if ($file === null) { break; } - $track = $this->dbRowToTrack($row, $userFolder, $userFolder, true, [] ); + $track = $this->dbRowToTrack($row, $userFolder, $userFolder, true, []); } else { $track = [ 'id' => intval($row['id']), @@ -415,662 +418,648 @@ public function getTrackByFileIDFromDB($fileId, $userId=null) { 'file_path' => '', ]; } - break; - } - $req->closeCursor(); - $qb = $qb->resetQueryParts(); - return $track; - } - - public function addTrackToDB($userId, $fileId, $file) { - $metadata = ''; - $etag = $file->getEtag(); - $qb = $this->qb; - $qb->insert('maps_tracks') - ->values([ - 'user_id' => $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR), - 'file_id' => $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT), - 'metadata' => $qb->createNamedParameter($metadata, IQueryBuilder::PARAM_STR), - 'etag' => $qb->createNamedParameter($etag, IQueryBuilder::PARAM_STR) - ]); - $req = $qb->execute(); - $trackId = $qb->getLastInsertId(); - $qb = $qb->resetQueryParts(); - return $trackId; - } - - public function editTrackInDB($id, $color, $metadata, $etag) { - $qb = $this->qb; - $qb->update('maps_tracks'); - if ($color !== null) { - $qb->set('color', $qb->createNamedParameter($color, IQueryBuilder::PARAM_STR)); - } - if ($metadata !== null) { - $qb->set('metadata', $qb->createNamedParameter($metadata, IQueryBuilder::PARAM_STR)); - } - if ($etag !== null) { - $qb->set('etag', $qb->createNamedParameter($etag, IQueryBuilder::PARAM_STR)); - } - $qb->where( - $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - - public function deleteByFileId($fileId) { - $qb = $this->qb; - $qb->delete('maps_tracks') - ->where( - $qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - - public function deleteByFileIdUserId($fileId, $userId) { - $qb = $this->qb; - $qb->delete('maps_tracks') - ->where( - $qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)) - ) - ->andWhere( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - - public function deleteTrackFromDB($id) { - $qb = $this->qb; - $qb->delete('maps_tracks') - ->where( - $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - - public function deleteAllTracksFromDB($userId) { - $qb = $this->qb; - $qb->delete('maps_tracks') - ->where( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - - public function deleteTracksFromDB($ids, $userId) { - $qb = $this->qb; - $qb->delete('maps_tracks') - ->where( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) - ); - if (count($ids) > 0) { - $or = $qb->expr()->orx(); - foreach ($ids as $id) { - $or->add($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT))); - } - $qb->andWhere($or); - } - else { - return; - } - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - - public function generateTrackMetadata($file) { - $DISTANCE_BETWEEN_SHORT_POINTS = 300; - $STOPPED_SPEED_THRESHOLD = 0.9; - - $name = $file->getName(); - $gpx_content = $file->getContent(); - - $lat = '0'; - $lon = '0'; - $total_distance = 0; - $total_duration = 0; - $date_begin = null; - $date_end = null; - - $distAccCumulEle = 0; - $pos_elevation = 0; - $neg_elevation = 0; - $min_elevation = null; - $max_elevation = null; - - $avg_speed = '???'; - $moving_time = 0; - $moving_distance = 0; - $stopped_distance = 0; - $moving_max_speed = 0; - $moving_avg_speed = 0; - $stopped_time = 0; - $north = null; - $south = null; - $east = null; - $west = null; - $trackNameList = []; - $linkurl = ''; - $linktext = ''; - - $pointsBySegment = []; - $lastTime = null; - - try{ - $gpx = new \SimpleXMLElement($gpx_content); - } - catch (\Throwable $e) { - $this->logger->error( - "Exception in ".$name." gpx parsing : ".$e->getMessage(), - ['app' => 'maps'] - ); - return null; - } - - if (count($gpx->trk) === 0 and count($gpx->rte) === 0 and count($gpx->wpt) === 0){ - $this->logger->error( - 'Nothing to parse in '.$name.' gpx file', - ['app' => 'maps'] - ); - return null; - } - - // METADATA - if (!empty($gpx->metadata) and !empty($gpx->metadata->link)) { - $linkurl = $gpx->metadata->link['href']; - if (!empty($gpx->metadata->link->text)) { - $linktext = $gpx->metadata->link->text; - } - } - - // TRACKS - foreach ($gpx->trk as $track) { - $trackname = str_replace("\n", '', $track->name); - if (empty($trackname)) { - $trackname = ''; - } - $trackname = str_replace('"', "'", $trackname); - $trackNameList[] = sprintf('"%s"', $trackname); - foreach ($track->trkseg as $segment) { - $lastPoint = null; - $lastTime = null; - $pointIndex = 0; - $pointsBySegment[] = $segment->trkpt; - foreach ($segment->trkpt as $point) { - if (empty($point['lat']) or empty($point['lon'])) { - continue; - } - if (empty($point->ele)) { - $pointele = null; - } - else{ - $pointele = floatval($point->ele); - } - if (empty($point->time)) { - $pointtime = null; - } - else{ - $pointtime = new \DateTime($point->time); - } - if ($lastPoint !== null and (!empty($lastPoint->ele))){ - $lastPointele = floatval($lastPoint->ele); - } - else{ - $lastPointele = null; - } - if ($lastPoint !== null and (!empty($lastPoint->time))){ - $lastTime = new \DateTime($lastPoint->time); - } - else{ - $lastTime = null; - } - if ($lastPoint !== null){ - $distToLast = distance($lastPoint, $point); - } - else{ - $distToLast = null; - } - $pointlat = floatval($point['lat']); - $pointlon = floatval($point['lon']); - if ($pointIndex === 0){ - if ($lat === '0' and $lon === '0'){ - $lat = $pointlat; - $lon = $pointlon; - } - if ($pointtime !== null and ($date_begin === null or $pointtime < $date_begin)){ - $date_begin = $pointtime; - } - $downBegin = $pointele; - if ($north === null){ - $north = $pointlat; - $south = $pointlat; - $east = $pointlon; - $west = $pointlon; - } - } - - if ($pointlat > $north){ - $north = $pointlat; - } - if ($pointlat < $south){ - $south = $pointlat; - } - if ($pointlon > $east){ - $east = $pointlon; - } - if ($pointlon < $west){ - $west = $pointlon; - } - if ($pointele !== null and ($min_elevation === null or $pointele < $min_elevation)){ - $min_elevation = $pointele; - } - if ($pointele !== null and ($max_elevation === null or $pointele > $max_elevation)){ - $max_elevation = $pointele; - } - if ($lastPoint !== null and $pointtime !== null and $lastTime !== null){ - $t = abs($lastTime->getTimestamp() - $pointtime->getTimestamp()); - - $speed = 0; - if ($t > 0){ - $speed = $distToLast / $t; - $speed = $speed / 1000; - $speed = $speed * 3600; - } - - if ($speed <= $STOPPED_SPEED_THRESHOLD){ - $stopped_time += $t; - $stopped_distance += $distToLast; - } else { - $moving_time += $t; - $moving_distance += $distToLast; - } - } - if ($lastPoint !== null){ - $total_distance += $distToLast; - } - - $lastPoint = $point; - $pointIndex += 1; - } - - if ($lastTime !== null and ($date_end === null or $lastTime > $date_end)){ - $date_end = $lastTime; - } - } - - } - - # ROUTES - foreach ($gpx->rte as $route) { - $routename = str_replace("\n", '', $route->name); - if (empty($routename)){ - $routename = ''; - } - $routename = str_replace('"', "'", $routename); - $trackNameList[] = sprintf('"%s"', $routename); - - $lastPoint = null; - $lastTime = null; - $pointIndex = 0; - $pointsBySegment[] = $route->rtept; - foreach ($route->rtept as $point) { - if (empty($point['lat']) or empty($point['lon'])) { - continue; - } - if (empty($point->ele)){ - $pointele = null; - } - else{ - $pointele = floatval($point->ele); - } - if (empty($point->time)){ - $pointtime = null; - } - else{ - $pointtime = new \DateTime($point->time); - } - if ($lastPoint !== null and (!empty($lastPoint->ele))){ - $lastPointele = floatval($lastPoint->ele); - } - else{ - $lastPointele = null; - } - if ($lastPoint !== null and (!empty($lastPoint->time))){ - $lastTime = new \DateTime($lastPoint->time); - } - else{ - $lastTime = null; - } - if ($lastPoint !== null){ - $distToLast = distance($lastPoint, $point); - } - else{ - $distToLast = null; - } - $pointlat = floatval($point['lat']); - $pointlon = floatval($point['lon']); - if ($pointIndex === 0){ - if ($lat === '0' and $lon === '0'){ - $lat = $pointlat; - $lon = $pointlon; - } - if ($pointtime !== null and ($date_begin === null or $pointtime < $date_begin)){ - $date_begin = $pointtime; - } - $downBegin = $pointele; - if ($north === null){ - $north = $pointlat; - $south = $pointlat; - $east = $pointlon; - $west = $pointlon; - } - } - - if ($pointlat > $north){ - $north = $pointlat; - } - if ($pointlat < $south){ - $south = $pointlat; - } - if ($pointlon > $east){ - $east = $pointlon; - } - if ($pointlon < $west){ - $west = $pointlon; - } - if ($pointele !== null and ($min_elevation === null or $pointele < $min_elevation)){ - $min_elevation = $pointele; - } - if ($pointele !== null and ($max_elevation === null or $pointele > $max_elevation)){ - $max_elevation = $pointele; - } - if ($lastPoint !== null and $pointtime !== null and $lastTime !== null){ - $t = abs($lastTime->getTimestamp() - $pointtime->getTimestamp()); - - $speed = 0; - if ($t > 0){ - $speed = $distToLast / $t; - $speed = $speed / 1000; - $speed = $speed * 3600; - } - - if ($speed <= $STOPPED_SPEED_THRESHOLD){ - $stopped_time += $t; - $stopped_distance += $distToLast; - } - else{ - $moving_time += $t; - $moving_distance += $distToLast; - } - } - if ($lastPoint !== null){ - $total_distance += $distToLast; - } - - $lastPoint = $point; - $pointIndex += 1; - } - - if ($lastTime !== null and ($date_end === null or $lastTime > $date_end)){ - $date_end = $lastTime; - } - } - - # TOTAL STATS : duration, avg speed, avg_moving_speed - if ($date_end !== null and $date_begin !== null){ - $totsec = abs($date_end->getTimestamp() - $date_begin->getTimestamp()); - $total_duration = $totsec; - if ($totsec === 0){ - $avg_speed = 0; - } - else{ - $avg_speed = $total_distance / $totsec; - $avg_speed = $avg_speed / 1000; - $avg_speed = $avg_speed * 3600; - $avg_speed = sprintf('%.2f', $avg_speed); - } - } - - // determination of real moving average speed from moving time - $moving_avg_speed = 0; - $moving_pace = 0; - if ($moving_time > 0){ - $moving_avg_speed = $total_distance / $moving_time; - $moving_avg_speed = $moving_avg_speed / 1000; - $moving_avg_speed = $moving_avg_speed * 3600; - $moving_avg_speed = sprintf('%.2f', $moving_avg_speed); - // pace in minutes/km - $moving_pace = $moving_time / $total_distance; - $moving_pace = $moving_pace / 60; - $moving_pace = $moving_pace * 1000; - $moving_pace = sprintf('%.2f', $moving_pace); - } - - # WAYPOINTS - foreach($gpx->wpt as $waypoint){ - $waypointlat = floatval($waypoint['lat']); - $waypointlon = floatval($waypoint['lon']); - - if ($lat === '0' and $lon === '0'){ - $lat = $waypointlat; - $lon = $waypointlon; - } - - if ($north === null or $waypointlat > $north){ - $north = $waypointlat; - } - if ($south === null or $waypointlat < $south){ - $south = $waypointlat; - } - if ($east === null or $waypointlon > $east){ - $east = $waypointlon; - } - if ($west === null or $waypointlon < $west){ - $west = $waypointlon; - } - } - - $trackNameList = '[' . implode(',', $trackNameList) . ']'; - if ($north === null){ - $north = 0; - } - if ($south === null){ - $south = 0; - } - if ($east === null){ - $east = 0; - } - if ($west === null){ - $west = 0; - } - - // we filter all segments by distance - $distFilteredPointsBySegment = []; - foreach ($pointsBySegment as $points) { - $distFilteredPointsBySegment[] = $this->getDistanceFilteredPoints($points); - } - // and we get points with elevation and time for each segment - $pointsWithElevationBySegment = []; - $pointsWithTimeBySegment = []; - foreach ($distFilteredPointsBySegment as $points) { - $pointsWithTimeOneSegment = []; - $pointsWithElevationOneSegment = []; - foreach ($points as $point) { - if (!empty($point->ele)) { - $pointsWithElevationOneSegment[] = $point; - } - if (!empty($point->time)) { - $pointsWithTimeOneSegment[] = $point; - } - } - $pointsWithElevationBySegment[] = $pointsWithElevationOneSegment; - $pointsWithTimeBySegment[] = $pointsWithTimeOneSegment; - } - // process elevation gain/loss - $pos_elevation = 0; - $neg_elevation = 0; - foreach ($pointsWithElevationBySegment as $points) { - $gainLoss = $this->getElevationGainLoss($points); - $pos_elevation += $gainLoss[0]; - $neg_elevation += $gainLoss[1]; - } - $pos_elevation = number_format($pos_elevation, 2, '.', ''); - $neg_elevation = number_format($neg_elevation, 2, '.', ''); - // process max speed from distance filtered points - $maxSpeed = 0; - foreach ($pointsWithTimeBySegment as $points) { - $segmentMaxSpeed = $this->getMaxSpeed($points); - if ($segmentMaxSpeed > $maxSpeed) { - $maxSpeed = $segmentMaxSpeed; - } - } - - $result = sprintf('{"lat":%s, "lng":%s, "name": "%s", "distance": %.3f, "duration": %d, "begin": %d, "end": %d, "posel": %.2f, "negel": %.2f, "minel": %.2f, "maxel": %.2f, "maxspd": %.2f, "avgspd": %.2f, "movtime": %d, "stptime": %d, "movavgspd": %s, "n": %.8f, "s": %.8f, "e": %.8f, "w": %.8f, "trnl": %s, "lnkurl": "%s", "lnktxt": "%s", "movpace": %.2f}', - $lat, - $lon, - str_replace('"', "'", $name), - $total_distance, - $total_duration, - ($date_begin !== null) ? $date_begin->getTimestamp() : -1, - ($date_end !== null) ? $date_end->getTimestamp() : -1, - $pos_elevation, - $neg_elevation, - ($min_elevation !== null) ? $min_elevation : -1000, - ($max_elevation !== null) ? $max_elevation : -1000, - $maxSpeed, - $avg_speed, - $moving_time, - $stopped_time, - $moving_avg_speed, - $north, - $south, - $east, - $west, - (strlen($trackNameList) < 200) ? $trackNameList : '[]', - str_replace('"', "'", $linkurl), - str_replace('"', "'", $linktext), - $moving_pace - ); - return $result; - } - - private function getDistanceFilteredPoints($points) { - $DISTANCE_THRESHOLD = 10; - - $distFilteredPoints = []; - if (count($points) > 0) { - array_push($distFilteredPoints, $points[0]); - $lastPoint = $points[0]; - foreach ($points as $point) { - if (distance($lastPoint, $point) >= $DISTANCE_THRESHOLD) { - array_push($distFilteredPoints, $point); - $lastPoint = $point; - } - } - } - - return $distFilteredPoints; - } - - private function getMaxSpeed($points) { - $maxSpeed = 0; - - if (count($points) > 0) { - $lastPoint = $points[0]; - $lastTime = new \DateTime($lastPoint->time); - foreach ($points as $point) { - $time = new \DateTime($point->time); - $timeDelta = abs($lastTime->getTimestamp() - $time->getTimestamp()); - if ($timeDelta > 0) { - $distance = distance($point, $lastPoint); - $speed = $distance / $timeDelta; - $speed = $speed / 1000; - $speed = $speed * 3600; - if ($speed > $maxSpeed) { - $maxSpeed = $speed; - } - } - $lastTime = $time; - $lastPoint = $point; - } - } - - return $maxSpeed; - } - - /** - * inspired by https://www.gpsvisualizer.com/tutorials/elevation_gain.html - */ - private function getElevationGainLoss($points) { - $ELEVATION_THRESHOLD = 6; - $gain = 0; - $loss = 0; - - // then calculate elevation gain with elevation threshold - if (count($points) > 0) { - $validPoint = $points[0]; - foreach ($points as $point) { - $deniv = floatval($point->ele) - floatval($validPoint->ele); - if ($deniv >= $ELEVATION_THRESHOLD) { - $gain += $deniv; - $validPoint = $point; - } else if (-$deniv >= $ELEVATION_THRESHOLD) { - $loss -= $deniv; - $validPoint = $point; - } - } - } - - return [$gain, $loss]; - } + break; + } + $req->closeCursor(); + $qb = $qb->resetQueryParts(); + return $track; + } + + public function addTrackToDB($userId, $fileId, $file) { + $metadata = ''; + $etag = $file->getEtag(); + $qb = $this->qb; + $qb->insert('maps_tracks') + ->values([ + 'user_id' => $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR), + 'file_id' => $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT), + 'metadata' => $qb->createNamedParameter($metadata, IQueryBuilder::PARAM_STR), + 'etag' => $qb->createNamedParameter($etag, IQueryBuilder::PARAM_STR) + ]); + $req = $qb->execute(); + $trackId = $qb->getLastInsertId(); + $qb = $qb->resetQueryParts(); + return $trackId; + } + + public function editTrackInDB($id, $color, $metadata, $etag) { + $qb = $this->qb; + $qb->update('maps_tracks'); + if ($color !== null) { + $qb->set('color', $qb->createNamedParameter($color, IQueryBuilder::PARAM_STR)); + } + if ($metadata !== null) { + $qb->set('metadata', $qb->createNamedParameter($metadata, IQueryBuilder::PARAM_STR)); + } + if ($etag !== null) { + $qb->set('etag', $qb->createNamedParameter($etag, IQueryBuilder::PARAM_STR)); + } + $qb->where( + $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + + public function deleteByFileId($fileId) { + $qb = $this->qb; + $qb->delete('maps_tracks') + ->where( + $qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + + public function deleteByFileIdUserId($fileId, $userId) { + $qb = $this->qb; + $qb->delete('maps_tracks') + ->where( + $qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)) + ) + ->andWhere( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + + public function deleteTrackFromDB($id) { + $qb = $this->qb; + $qb->delete('maps_tracks') + ->where( + $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + + public function deleteAllTracksFromDB($userId) { + $qb = $this->qb; + $qb->delete('maps_tracks') + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + + public function deleteTracksFromDB($ids, $userId) { + $qb = $this->qb; + $qb->delete('maps_tracks') + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)) + ); + if (count($ids) > 0) { + $or = $qb->expr()->orx(); + foreach ($ids as $id) { + $or->add($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT))); + } + $qb->andWhere($or); + } else { + return; + } + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + + public function generateTrackMetadata($file) { + $DISTANCE_BETWEEN_SHORT_POINTS = 300; + $STOPPED_SPEED_THRESHOLD = 0.9; + + $name = $file->getName(); + $gpx_content = $file->getContent(); + + $lat = '0'; + $lon = '0'; + $total_distance = 0; + $total_duration = 0; + $date_begin = null; + $date_end = null; + + $distAccCumulEle = 0; + $pos_elevation = 0; + $neg_elevation = 0; + $min_elevation = null; + $max_elevation = null; + + $avg_speed = '???'; + $moving_time = 0; + $moving_distance = 0; + $stopped_distance = 0; + $moving_max_speed = 0; + $moving_avg_speed = 0; + $stopped_time = 0; + $north = null; + $south = null; + $east = null; + $west = null; + $trackNameList = []; + $linkurl = ''; + $linktext = ''; + + $pointsBySegment = []; + $lastTime = null; + + try { + $gpx = new \SimpleXMLElement($gpx_content); + } catch (\Throwable $e) { + $this->logger->error( + 'Exception in '.$name.' gpx parsing : '.$e->getMessage(), + ['app' => 'maps'] + ); + return null; + } + + if (count($gpx->trk) === 0 and count($gpx->rte) === 0 and count($gpx->wpt) === 0) { + $this->logger->error( + 'Nothing to parse in '.$name.' gpx file', + ['app' => 'maps'] + ); + return null; + } + + // METADATA + if (!empty($gpx->metadata) and !empty($gpx->metadata->link)) { + $linkurl = $gpx->metadata->link['href']; + if (!empty($gpx->metadata->link->text)) { + $linktext = $gpx->metadata->link->text; + } + } + + // TRACKS + foreach ($gpx->trk as $track) { + $trackname = str_replace("\n", '', $track->name); + if (empty($trackname)) { + $trackname = ''; + } + $trackname = str_replace('"', "'", $trackname); + $trackNameList[] = sprintf('"%s"', $trackname); + foreach ($track->trkseg as $segment) { + $lastPoint = null; + $lastTime = null; + $pointIndex = 0; + $pointsBySegment[] = $segment->trkpt; + foreach ($segment->trkpt as $point) { + if (empty($point['lat']) or empty($point['lon'])) { + continue; + } + if (empty($point->ele)) { + $pointele = null; + } else { + $pointele = floatval($point->ele); + } + if (empty($point->time)) { + $pointtime = null; + } else { + $pointtime = new \DateTime($point->time); + } + if ($lastPoint !== null and (!empty($lastPoint->ele))) { + $lastPointele = floatval($lastPoint->ele); + } else { + $lastPointele = null; + } + if ($lastPoint !== null and (!empty($lastPoint->time))) { + $lastTime = new \DateTime($lastPoint->time); + } else { + $lastTime = null; + } + if ($lastPoint !== null) { + $distToLast = distance($lastPoint, $point); + } else { + $distToLast = null; + } + $pointlat = floatval($point['lat']); + $pointlon = floatval($point['lon']); + if ($pointIndex === 0) { + if ($lat === '0' and $lon === '0') { + $lat = $pointlat; + $lon = $pointlon; + } + if ($pointtime !== null and ($date_begin === null or $pointtime < $date_begin)) { + $date_begin = $pointtime; + } + $downBegin = $pointele; + if ($north === null) { + $north = $pointlat; + $south = $pointlat; + $east = $pointlon; + $west = $pointlon; + } + } + + if ($pointlat > $north) { + $north = $pointlat; + } + if ($pointlat < $south) { + $south = $pointlat; + } + if ($pointlon > $east) { + $east = $pointlon; + } + if ($pointlon < $west) { + $west = $pointlon; + } + if ($pointele !== null and ($min_elevation === null or $pointele < $min_elevation)) { + $min_elevation = $pointele; + } + if ($pointele !== null and ($max_elevation === null or $pointele > $max_elevation)) { + $max_elevation = $pointele; + } + if ($lastPoint !== null and $pointtime !== null and $lastTime !== null) { + $t = abs($lastTime->getTimestamp() - $pointtime->getTimestamp()); + + $speed = 0; + if ($t > 0) { + $speed = $distToLast / $t; + $speed = $speed / 1000; + $speed = $speed * 3600; + } + + if ($speed <= $STOPPED_SPEED_THRESHOLD) { + $stopped_time += $t; + $stopped_distance += $distToLast; + } else { + $moving_time += $t; + $moving_distance += $distToLast; + } + } + if ($lastPoint !== null) { + $total_distance += $distToLast; + } + + $lastPoint = $point; + $pointIndex += 1; + } + + if ($lastTime !== null and ($date_end === null or $lastTime > $date_end)) { + $date_end = $lastTime; + } + } + + } + + # ROUTES + foreach ($gpx->rte as $route) { + $routename = str_replace("\n", '', $route->name); + if (empty($routename)) { + $routename = ''; + } + $routename = str_replace('"', "'", $routename); + $trackNameList[] = sprintf('"%s"', $routename); + + $lastPoint = null; + $lastTime = null; + $pointIndex = 0; + $pointsBySegment[] = $route->rtept; + foreach ($route->rtept as $point) { + if (empty($point['lat']) or empty($point['lon'])) { + continue; + } + if (empty($point->ele)) { + $pointele = null; + } else { + $pointele = floatval($point->ele); + } + if (empty($point->time)) { + $pointtime = null; + } else { + $pointtime = new \DateTime($point->time); + } + if ($lastPoint !== null and (!empty($lastPoint->ele))) { + $lastPointele = floatval($lastPoint->ele); + } else { + $lastPointele = null; + } + if ($lastPoint !== null and (!empty($lastPoint->time))) { + $lastTime = new \DateTime($lastPoint->time); + } else { + $lastTime = null; + } + if ($lastPoint !== null) { + $distToLast = distance($lastPoint, $point); + } else { + $distToLast = null; + } + $pointlat = floatval($point['lat']); + $pointlon = floatval($point['lon']); + if ($pointIndex === 0) { + if ($lat === '0' and $lon === '0') { + $lat = $pointlat; + $lon = $pointlon; + } + if ($pointtime !== null and ($date_begin === null or $pointtime < $date_begin)) { + $date_begin = $pointtime; + } + $downBegin = $pointele; + if ($north === null) { + $north = $pointlat; + $south = $pointlat; + $east = $pointlon; + $west = $pointlon; + } + } + + if ($pointlat > $north) { + $north = $pointlat; + } + if ($pointlat < $south) { + $south = $pointlat; + } + if ($pointlon > $east) { + $east = $pointlon; + } + if ($pointlon < $west) { + $west = $pointlon; + } + if ($pointele !== null and ($min_elevation === null or $pointele < $min_elevation)) { + $min_elevation = $pointele; + } + if ($pointele !== null and ($max_elevation === null or $pointele > $max_elevation)) { + $max_elevation = $pointele; + } + if ($lastPoint !== null and $pointtime !== null and $lastTime !== null) { + $t = abs($lastTime->getTimestamp() - $pointtime->getTimestamp()); + + $speed = 0; + if ($t > 0) { + $speed = $distToLast / $t; + $speed = $speed / 1000; + $speed = $speed * 3600; + } + + if ($speed <= $STOPPED_SPEED_THRESHOLD) { + $stopped_time += $t; + $stopped_distance += $distToLast; + } else { + $moving_time += $t; + $moving_distance += $distToLast; + } + } + if ($lastPoint !== null) { + $total_distance += $distToLast; + } + + $lastPoint = $point; + $pointIndex += 1; + } + + if ($lastTime !== null and ($date_end === null or $lastTime > $date_end)) { + $date_end = $lastTime; + } + } + + # TOTAL STATS : duration, avg speed, avg_moving_speed + if ($date_end !== null and $date_begin !== null) { + $totsec = abs($date_end->getTimestamp() - $date_begin->getTimestamp()); + $total_duration = $totsec; + if ($totsec === 0) { + $avg_speed = 0; + } else { + $avg_speed = $total_distance / $totsec; + $avg_speed = $avg_speed / 1000; + $avg_speed = $avg_speed * 3600; + $avg_speed = sprintf('%.2f', $avg_speed); + } + } + + // determination of real moving average speed from moving time + $moving_avg_speed = 0; + $moving_pace = 0; + if ($moving_time > 0) { + $moving_avg_speed = $total_distance / $moving_time; + $moving_avg_speed = $moving_avg_speed / 1000; + $moving_avg_speed = $moving_avg_speed * 3600; + $moving_avg_speed = sprintf('%.2f', $moving_avg_speed); + // pace in minutes/km + $moving_pace = $moving_time / $total_distance; + $moving_pace = $moving_pace / 60; + $moving_pace = $moving_pace * 1000; + $moving_pace = sprintf('%.2f', $moving_pace); + } + + # WAYPOINTS + foreach ($gpx->wpt as $waypoint) { + $waypointlat = floatval($waypoint['lat']); + $waypointlon = floatval($waypoint['lon']); + + if ($lat === '0' and $lon === '0') { + $lat = $waypointlat; + $lon = $waypointlon; + } + + if ($north === null or $waypointlat > $north) { + $north = $waypointlat; + } + if ($south === null or $waypointlat < $south) { + $south = $waypointlat; + } + if ($east === null or $waypointlon > $east) { + $east = $waypointlon; + } + if ($west === null or $waypointlon < $west) { + $west = $waypointlon; + } + } + + $trackNameList = '[' . implode(',', $trackNameList) . ']'; + if ($north === null) { + $north = 0; + } + if ($south === null) { + $south = 0; + } + if ($east === null) { + $east = 0; + } + if ($west === null) { + $west = 0; + } + + // we filter all segments by distance + $distFilteredPointsBySegment = []; + foreach ($pointsBySegment as $points) { + $distFilteredPointsBySegment[] = $this->getDistanceFilteredPoints($points); + } + // and we get points with elevation and time for each segment + $pointsWithElevationBySegment = []; + $pointsWithTimeBySegment = []; + foreach ($distFilteredPointsBySegment as $points) { + $pointsWithTimeOneSegment = []; + $pointsWithElevationOneSegment = []; + foreach ($points as $point) { + if (!empty($point->ele)) { + $pointsWithElevationOneSegment[] = $point; + } + if (!empty($point->time)) { + $pointsWithTimeOneSegment[] = $point; + } + } + $pointsWithElevationBySegment[] = $pointsWithElevationOneSegment; + $pointsWithTimeBySegment[] = $pointsWithTimeOneSegment; + } + // process elevation gain/loss + $pos_elevation = 0; + $neg_elevation = 0; + foreach ($pointsWithElevationBySegment as $points) { + $gainLoss = $this->getElevationGainLoss($points); + $pos_elevation += $gainLoss[0]; + $neg_elevation += $gainLoss[1]; + } + $pos_elevation = number_format($pos_elevation, 2, '.', ''); + $neg_elevation = number_format($neg_elevation, 2, '.', ''); + // process max speed from distance filtered points + $maxSpeed = 0; + foreach ($pointsWithTimeBySegment as $points) { + $segmentMaxSpeed = $this->getMaxSpeed($points); + if ($segmentMaxSpeed > $maxSpeed) { + $maxSpeed = $segmentMaxSpeed; + } + } + + $result = sprintf('{"lat":%s, "lng":%s, "name": "%s", "distance": %.3f, "duration": %d, "begin": %d, "end": %d, "posel": %.2f, "negel": %.2f, "minel": %.2f, "maxel": %.2f, "maxspd": %.2f, "avgspd": %.2f, "movtime": %d, "stptime": %d, "movavgspd": %s, "n": %.8f, "s": %.8f, "e": %.8f, "w": %.8f, "trnl": %s, "lnkurl": "%s", "lnktxt": "%s", "movpace": %.2f}', + $lat, + $lon, + str_replace('"', "'", $name), + $total_distance, + $total_duration, + ($date_begin !== null) ? $date_begin->getTimestamp() : -1, + ($date_end !== null) ? $date_end->getTimestamp() : -1, + $pos_elevation, + $neg_elevation, + ($min_elevation !== null) ? $min_elevation : -1000, + ($max_elevation !== null) ? $max_elevation : -1000, + $maxSpeed, + $avg_speed, + $moving_time, + $stopped_time, + $moving_avg_speed, + $north, + $south, + $east, + $west, + (strlen($trackNameList) < 200) ? $trackNameList : '[]', + str_replace('"', "'", $linkurl), + str_replace('"', "'", $linktext), + $moving_pace + ); + return $result; + } + + private function getDistanceFilteredPoints($points) { + $DISTANCE_THRESHOLD = 10; + + $distFilteredPoints = []; + if (count($points) > 0) { + array_push($distFilteredPoints, $points[0]); + $lastPoint = $points[0]; + foreach ($points as $point) { + if (distance($lastPoint, $point) >= $DISTANCE_THRESHOLD) { + array_push($distFilteredPoints, $point); + $lastPoint = $point; + } + } + } + + return $distFilteredPoints; + } + + private function getMaxSpeed($points) { + $maxSpeed = 0; + + if (count($points) > 0) { + $lastPoint = $points[0]; + $lastTime = new \DateTime($lastPoint->time); + foreach ($points as $point) { + $time = new \DateTime($point->time); + $timeDelta = abs($lastTime->getTimestamp() - $time->getTimestamp()); + if ($timeDelta > 0) { + $distance = distance($point, $lastPoint); + $speed = $distance / $timeDelta; + $speed = $speed / 1000; + $speed = $speed * 3600; + if ($speed > $maxSpeed) { + $maxSpeed = $speed; + } + } + $lastTime = $time; + $lastPoint = $point; + } + } + + return $maxSpeed; + } + + /** + * inspired by https://www.gpsvisualizer.com/tutorials/elevation_gain.html + */ + private function getElevationGainLoss($points) { + $ELEVATION_THRESHOLD = 6; + $gain = 0; + $loss = 0; + + // then calculate elevation gain with elevation threshold + if (count($points) > 0) { + $validPoint = $points[0]; + foreach ($points as $point) { + $deniv = floatval($point->ele) - floatval($validPoint->ele); + if ($deniv >= $ELEVATION_THRESHOLD) { + $gain += $deniv; + $validPoint = $point; + } elseif (-$deniv >= $ELEVATION_THRESHOLD) { + $loss -= $deniv; + $validPoint = $point; + } + } + } + + return [$gain, $loss]; + } } /* * return distance between these two gpx points in meters */ -function distance($p1, $p2){ - - $lat1 = (float)$p1['lat']; - $long1 = (float)$p1['lon']; - $lat2 = (float)$p2['lat']; - $long2 = (float)$p2['lon']; - - if ($lat1 === $lat2 and $long1 === $long2){ - return 0; - } - - // Convert latitude and longitude to - // spherical coordinates in radians. - $degrees_to_radians = pi()/180.0; - - // phi = 90 - latitude - $phi1 = (90.0 - $lat1)*$degrees_to_radians; - $phi2 = (90.0 - $lat2)*$degrees_to_radians; - - // theta = longitude - $theta1 = $long1*$degrees_to_radians; - $theta2 = $long2*$degrees_to_radians; - - // Compute spherical distance from spherical coordinates. - - // For two locations in spherical coordinates - // (1, theta, phi) and (1, theta, phi) - // cosine( arc length ) = - // sin phi sin phi' cos(theta-theta') + cos phi cos phi' - // distance = rho * arc length - - $cos = (sin($phi1)*sin($phi2)*cos($theta1 - $theta2) + - cos($phi1)*cos($phi2)); - // why some cosinus are > than 1 ? - if ($cos > 1.0){ - $cos = 1.0; - } - $arc = acos($cos); - - // Remember to multiply arc by the radius of the earth - // in your favorite set of units to get length. - return $arc*6371000; +function distance($p1, $p2) { + + $lat1 = (float)$p1['lat']; + $long1 = (float)$p1['lon']; + $lat2 = (float)$p2['lat']; + $long2 = (float)$p2['lon']; + + if ($lat1 === $lat2 and $long1 === $long2) { + return 0; + } + + // Convert latitude and longitude to + // spherical coordinates in radians. + $degrees_to_radians = pi() / 180.0; + + // phi = 90 - latitude + $phi1 = (90.0 - $lat1) * $degrees_to_radians; + $phi2 = (90.0 - $lat2) * $degrees_to_radians; + + // theta = longitude + $theta1 = $long1 * $degrees_to_radians; + $theta2 = $long2 * $degrees_to_radians; + + // Compute spherical distance from spherical coordinates. + + // For two locations in spherical coordinates + // (1, theta, phi) and (1, theta, phi) + // cosine( arc length ) = + // sin phi sin phi' cos(theta-theta') + cos phi cos phi' + // distance = rho * arc length + + $cos = (sin($phi1) * sin($phi2) * cos($theta1 - $theta2) + + cos($phi1) * cos($phi2)); + // why some cosinus are > than 1 ? + if ($cos > 1.0) { + $cos = 1.0; + } + $arc = acos($cos); + + // Remember to multiply arc by the radius of the earth + // in your favorite set of units to get length. + return $arc * 6371000; } diff --git a/lib/Settings/AdminSettings.php b/lib/Settings/AdminSettings.php index f4410c82b..7665991ba 100644 --- a/lib/Settings/AdminSettings.php +++ b/lib/Settings/AdminSettings.php @@ -1,80 +1,80 @@ urlGenerator = $urlGenerator; - $this->iniWrapper = $iniWrapper; - $this->request = $request; - $this->l = $l; - $this->config = $config; - } + public function __construct( + IniGetWrapper $iniWrapper, + IL10N $l, + IRequest $request, + IConfig $config, + IURLGenerator $urlGenerator) { + $this->urlGenerator = $urlGenerator; + $this->iniWrapper = $iniWrapper; + $this->request = $request; + $this->l = $l; + $this->config = $config; + } - /** - * @return TemplateResponse - */ - public function getForm() { - $keys = [ - 'osrmCarURL', - 'osrmBikeURL', - 'osrmFootURL', - 'osrmDEMO', - 'graphhopperAPIKEY', - 'mapboxAPIKEY', + /** + * @return TemplateResponse + */ + public function getForm() { + $keys = [ + 'osrmCarURL', + 'osrmBikeURL', + 'osrmFootURL', + 'osrmDEMO', + 'graphhopperAPIKEY', + 'mapboxAPIKEY', 'maplibreStreetStyleURL', 'maplibreStreetStyleAuth', - 'graphhopperURL' - ]; - $parameters = []; - foreach ($keys as $k) { - $v = $this->config->getAppValue('maps', $k); - $parameters[$k] = $v; - } + 'graphhopperURL' + ]; + $parameters = []; + foreach ($keys as $k) { + $v = $this->config->getAppValue('maps', $k); + $parameters[$k] = $v; + } - return new TemplateResponse('maps', 'adminSettings', $parameters, ''); - } + return new TemplateResponse('maps', 'adminSettings', $parameters, ''); + } - /** - * @return string the section ID, e.g. 'sharing' - */ - public function getSection() { - return 'additional'; - } + /** + * @return string the section ID, e.g. 'sharing' + */ + public function getSection() { + return 'additional'; + } - /** - * @return int whether the form should be rather on the top or bottom of - * the admin section. The forms are arranged in ascending order of the - * priority values. It is required to return a value between 0 and 100. - * - * E.g.: 70 - */ - public function getPriority() { - return 5; - } + /** + * @return int whether the form should be rather on the top or bottom of + * the admin section. The forms are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * + * E.g.: 70 + */ + public function getPriority() { + return 5; + } } diff --git a/templates/adminSettings.php b/templates/adminSettings.php index 0f1d8a2fa..0f895620c 100644 --- a/templates/adminSettings.php +++ b/templates/adminSettings.php @@ -4,7 +4,7 @@ style($appId, 'adminSettings'); $osrmDemoChecked = ''; if (!isset($_['osrmDEMO']) || $_['osrmDEMO'] === '1') { - $osrmDemoChecked = 'checked="checked"'; + $osrmDemoChecked = 'checked="checked"'; } ?> @@ -16,13 +16,19 @@

t('Leave URL fields empty to disable OSRM routing provider.')); ?>



-
+

-
+

-
+

/> @@ -34,9 +40,13 @@

-
+

- +

t('Mapbox settings')); ?>

@@ -44,7 +54,9 @@

t('Leave empty to disable.')); ?>



- +

t('MapLibre settings')); ?>

@@ -52,8 +64,12 @@

t('Leave empty to disable.')); ?>



-
+

- +

diff --git a/templates/main.php b/templates/main.php index 579525daf..047404f4e 100644 --- a/templates/main.php +++ b/templates/main.php @@ -1,5 +1,5 @@ +script($appId, $appId . '-report-error-map-action'); diff --git a/tests/Integration/AppTest.php b/tests/Integration/AppTest.php index 1ddc7d7a9..6c3911bd0 100644 --- a/tests/Integration/AppTest.php +++ b/tests/Integration/AppTest.php @@ -13,7 +13,6 @@ use OCP\AppFramework\App; - /** * This test shows how to make a small Integration Test. Query your class * directly from the container, only pass in mocks if needed and run your tests @@ -21,15 +20,15 @@ */ class AppTest extends \PHPUnit\Framework\TestCase { - private $container; + private $container; - protected function setUp(): void { - $app = new App('maps'); - $this->container = $app->getContainer(); - } + protected function setUp(): void { + $app = new App('maps'); + $this->container = $app->getContainer(); + } - public function testAppInstalled() { - $appManager = $this->container->query(\OCP\App\IAppManager::class); - $this->assertTrue($appManager->isInstalled('maps')); - } + public function testAppInstalled() { + $appManager = $this->container->query(\OCP\App\IAppManager::class); + $this->assertTrue($appManager->isInstalled('maps')); + } } diff --git a/tests/Integration/Db/FavoriteShareMapperTest.php b/tests/Integration/Db/FavoriteShareMapperTest.php index cacd6eb51..95e75ddff 100644 --- a/tests/Integration/Db/FavoriteShareMapperTest.php +++ b/tests/Integration/Db/FavoriteShareMapperTest.php @@ -24,7 +24,6 @@ namespace tests\Integration\Db; - use ChristophWurst\Nextcloud\Testing\DatabaseTransaction; use ChristophWurst\Nextcloud\Testing\TestCase; use OC; @@ -33,93 +32,93 @@ use OCP\AppFramework\Db\DoesNotExistException; class FavoriteShareMapperTest extends TestCase { - use DatabaseTransaction; + use DatabaseTransaction; - /* @var FavoriteShareMapper */ - private $mapper; + /* @var FavoriteShareMapper */ + private $mapper; - public function setUp(): void { - parent::setUp(); + public function setUp(): void { + parent::setUp(); - $this->mapper = new FavoriteShareMapper( - OC::$server->query(\OCP\IDBConnection::class), - OC::$server->getSecureRandom(), - OC::$server->getRootFolder() - ); - } + $this->mapper = new FavoriteShareMapper( + OC::$server->query(\OCP\IDBConnection::class), + OC::$server->getSecureRandom(), + OC::$server->getRootFolder() + ); + } - public function testCreateByOwnerAndTokenIsSuccessful() { - /* @var FavoriteShare */ - $share = $this->mapper->create("testUser", "testCategory"); + public function testCreateByOwnerAndTokenIsSuccessful() { + /* @var FavoriteShare */ + $share = $this->mapper->create('testUser', 'testCategory'); - $this->assertIsString($share->getToken()); - $this->assertEquals("testUser", $share->getOwner()); - $this->assertEquals("testCategory", $share->getCategory()); - } + $this->assertIsString($share->getToken()); + $this->assertEquals('testUser', $share->getOwner()); + $this->assertEquals('testCategory', $share->getCategory()); + } - public function testFindByTokenIsSuccessful() { - /* @var FavoriteShare */ - $shareExpected = $this->mapper->create("testUser", "testCategory"); + public function testFindByTokenIsSuccessful() { + /* @var FavoriteShare */ + $shareExpected = $this->mapper->create('testUser', 'testCategory'); - /* @var FavoriteShare */ - $shareActual = $this->mapper->findByToken($shareExpected->getToken()); + /* @var FavoriteShare */ + $shareActual = $this->mapper->findByToken($shareExpected->getToken()); - $this->assertEquals($shareExpected->getToken(), $shareActual->getToken()); - $this->assertEquals($shareExpected->getOwner(), $shareActual->getOwner()); - $this->assertEquals($shareExpected->getCategory(), $shareActual->getCategory()); - } + $this->assertEquals($shareExpected->getToken(), $shareActual->getToken()); + $this->assertEquals($shareExpected->getOwner(), $shareActual->getOwner()); + $this->assertEquals($shareExpected->getCategory(), $shareActual->getCategory()); + } - public function testFindByOwnerAndCategoryIsSuccessful() { - /* @var FavoriteShare */ - $shareExpected = $this->mapper->create("testUser", "testCategory"); + public function testFindByOwnerAndCategoryIsSuccessful() { + /* @var FavoriteShare */ + $shareExpected = $this->mapper->create('testUser', 'testCategory'); - /* @var FavoriteShare */ - $shareActual = $this->mapper->findByOwnerAndCategory("testUser", "testCategory"); + /* @var FavoriteShare */ + $shareActual = $this->mapper->findByOwnerAndCategory('testUser', 'testCategory'); - $this->assertEquals($shareExpected->getToken(), $shareActual->getToken()); - $this->assertEquals($shareExpected->getOwner(), $shareActual->getOwner()); - $this->assertEquals($shareExpected->getCategory(), $shareActual->getCategory()); - } + $this->assertEquals($shareExpected->getToken(), $shareActual->getToken()); + $this->assertEquals($shareExpected->getOwner(), $shareActual->getOwner()); + $this->assertEquals($shareExpected->getCategory(), $shareActual->getCategory()); + } - public function testFindAllByOwnerIsSuccessfulAndDoesNotContainOtherShares() { - /* @var FavoriteShare */ - $share1 = $this->mapper->create("testUser", "testCategory1"); + public function testFindAllByOwnerIsSuccessfulAndDoesNotContainOtherShares() { + /* @var FavoriteShare */ + $share1 = $this->mapper->create('testUser', 'testCategory1'); - /* @var FavoriteShare */ - $share2 = $this->mapper->create("testUser", "testCategory2"); + /* @var FavoriteShare */ + $share2 = $this->mapper->create('testUser', 'testCategory2'); - $this->mapper->create("testUser2", "testCategory"); + $this->mapper->create('testUser2', 'testCategory'); - /* @var array */ - $shares = $this->mapper->findAllByOwner("testUser"); + /* @var array */ + $shares = $this->mapper->findAllByOwner('testUser'); - $shareTokens = array_map(function ($share) { - return $share->getToken(); - }, $shares); + $shareTokens = array_map(function ($share) { + return $share->getToken(); + }, $shares); - $this->assertEquals(2, count($shareTokens)); - $this->assertContains($share1->getToken(), $shareTokens); - $this->assertContains($share2->getToken(), $shareTokens); - } + $this->assertEquals(2, count($shareTokens)); + $this->assertContains($share1->getToken(), $shareTokens); + $this->assertContains($share2->getToken(), $shareTokens); + } - public function testFindOrCreateByOwnerAndCategoryIsSuccessful() { - /* @var FavoriteShare */ - $share = $this->mapper->findOrCreateByOwnerAndCategory("testUser", "testCategory"); + public function testFindOrCreateByOwnerAndCategoryIsSuccessful() { + /* @var FavoriteShare */ + $share = $this->mapper->findOrCreateByOwnerAndCategory('testUser', 'testCategory'); - $this->assertIsString($share->getToken()); - $this->assertEquals("testUser", $share->getOwner()); - $this->assertEquals("testCategory", $share->getCategory()); - } + $this->assertIsString($share->getToken()); + $this->assertEquals('testUser', $share->getOwner()); + $this->assertEquals('testCategory', $share->getCategory()); + } - public function testRemoveByOwnerAndCategoryIsSuccessful() { - /* @var FavoriteShare */ - $share = $this->mapper->create("testUser", "testCategory"); + public function testRemoveByOwnerAndCategoryIsSuccessful() { + /* @var FavoriteShare */ + $share = $this->mapper->create('testUser', 'testCategory'); - $this->mapper->removeByOwnerAndCategory($share->getOwner(), $share->getCategory()); + $this->mapper->removeByOwnerAndCategory($share->getOwner(), $share->getCategory()); - $this->expectException(DoesNotExistException::class); + $this->expectException(DoesNotExistException::class); - $this->mapper->findByOwnerAndCategory($share->getOwner(), $share->getCategory()); - } + $this->mapper->findByOwnerAndCategory($share->getOwner(), $share->getCategory()); + } } diff --git a/tests/Unit/Controller/ContactsControllerTest.php b/tests/Unit/Controller/ContactsControllerTest.php index e2193157d..d06438c36 100644 --- a/tests/Unit/Controller/ContactsControllerTest.php +++ b/tests/Unit/Controller/ContactsControllerTest.php @@ -11,122 +11,116 @@ namespace OCA\Maps\Controller; -use \OCA\Maps\AppInfo\Application; -use \OCA\Maps\Service\DevicesService; -use OCP\AppFramework\Http\TemplateResponse; +use OCA\DAV\CardDAV\CardDavBackend; +use OCA\DAV\CardDAV\ContactsManager; use OCA\DAV\Connector\Sabre\Principal; +use OCA\Maps\AppInfo\Application; use OCA\Maps\Service\AddressService; -use OCP\Files\IAppData; -use \OCP\IServerContainer; -use \OCP\EventDispatcher\IEventDispatcher; -use \OCA\DAV\CardDAV\CardDavBackend; -use OCA\DAV\CardDAV\ContactsManager; -use OCP\IURLGenerator; - +use OCP\IServerContainer; class ContactsControllerTest extends \PHPUnit\Framework\TestCase { - private $appName; - private $request; - private $contacts; + private $appName; + private $request; + private $contacts; private $mapFolder; - private $container; - private $config; - private $app; + private $container; + private $config; + private $app; - private $contactsController; - private $contactsController2; - private $utilsController; - private $cdBackend; + private $contactsController; + private $contactsController2; + private $utilsController; + private $cdBackend; private $root; - public static function setUpBeforeClass(): void { - $app = new Application(); - $c = $app->getContainer(); - - $user = $c->getServer()->getUserManager()->get('test'); - $user2 = $c->getServer()->getUserManager()->get('test2'); - $user3 = $c->getServer()->getUserManager()->get('test3'); - $group = $c->getServer()->getGroupManager()->get('group1test'); - $group2 = $c->getServer()->getGroupManager()->get('group2test'); - - // CREATE DUMMY USERS - if ($user === null) { - $u1 = $c->getServer()->getUserManager()->createUser('test', 'tatotitoTUTU'); - $u1->setEMailAddress('toto@toto.net'); - } - if ($user2 === null) { - $u2 = $c->getServer()->getUserManager()->createUser('test2', 'plopinoulala000'); - } - if ($user2 === null) { - $u3 = $c->getServer()->getUserManager()->createUser('test3', 'yeyeahPASSPASS'); - } - if ($group === null) { - $c->getServer()->getGroupManager()->createGroup('group1test'); - $u1 = $c->getServer()->getUserManager()->get('test'); - $c->getServer()->getGroupManager()->get('group1test')->addUser($u1); - } - if ($group2 === null) { - $c->getServer()->getGroupManager()->createGroup('group2test'); - $u2 = $c->getServer()->getUserManager()->get('test2'); - $c->getServer()->getGroupManager()->get('group2test')->addUser($u2); - } - } - - protected function setUp(): void { - $this->app = new Application(); - $c = $this->app->getContainer(); - - $this->appName = 'maps'; - $this->request = $this->getMockBuilder('\OCP\IRequest') - ->disableOriginalConstructor() - ->getMock(); - $this->contacts = $this->getMockBuilder('OCP\Contacts\IManager') - ->disableOriginalConstructor() - ->getMock(); - - $urlGenerator = $c->getServer()->getURLGenerator(); - - $this->contactsManager = $c->query(IServerContainer::class)->getContactsManager(); - $this->cm = $c->query(ContactsManager::class); - $this->cm->setupContactsProvider($this->contactsManager, 'test', $urlGenerator); - - $this->app = new Application(); - $this->container = $this->app->getContainer(); - $c = $this->container; - $this->config = $c->query(IServerContainer::class)->getConfig(); - - $this->appData = $this->getMockBuilder('\OCP\Files\IAppData') - ->disableOriginalConstructor() - ->getMock(); - - $this->addressService = new AddressService( - $c->query(IServerContainer::class)->getMemCacheFactory(), - $c->query(IServerContainer::class)->getLogger(), - $c->query(IServerContainer::class)->getJobList(), - $this->appData, - $c->query(IServerContainer::class)->query(\OCP\IDBConnection::class) - ); - - //$this->userPrincipalBackend = new Principal( - // $c->getServer()->getUserManager(), - // $c->getServer()->getGroupManager(), - // $c->getServer()->getShareManager(), - // \OC::$server->getUserSession(), - // $c->query(IServerContainer::class)->getConfig(), - // \OC::$server->getAppManager() - //); - $this->userPrincipalBackend = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal') - ->disableOriginalConstructor() - ->getMock(); - - $this->cdBackend = $c->query(IServerContainer::class)->query(CardDavBackend::class); + public static function setUpBeforeClass(): void { + $app = new Application(); + $c = $app->getContainer(); + + $user = $c->getServer()->getUserManager()->get('test'); + $user2 = $c->getServer()->getUserManager()->get('test2'); + $user3 = $c->getServer()->getUserManager()->get('test3'); + $group = $c->getServer()->getGroupManager()->get('group1test'); + $group2 = $c->getServer()->getGroupManager()->get('group2test'); + + // CREATE DUMMY USERS + if ($user === null) { + $u1 = $c->getServer()->getUserManager()->createUser('test', 'tatotitoTUTU'); + $u1->setEMailAddress('toto@toto.net'); + } + if ($user2 === null) { + $u2 = $c->getServer()->getUserManager()->createUser('test2', 'plopinoulala000'); + } + if ($user2 === null) { + $u3 = $c->getServer()->getUserManager()->createUser('test3', 'yeyeahPASSPASS'); + } + if ($group === null) { + $c->getServer()->getGroupManager()->createGroup('group1test'); + $u1 = $c->getServer()->getUserManager()->get('test'); + $c->getServer()->getGroupManager()->get('group1test')->addUser($u1); + } + if ($group2 === null) { + $c->getServer()->getGroupManager()->createGroup('group2test'); + $u2 = $c->getServer()->getUserManager()->get('test2'); + $c->getServer()->getGroupManager()->get('group2test')->addUser($u2); + } + } + + protected function setUp(): void { + $this->app = new Application(); + $c = $this->app->getContainer(); + + $this->appName = 'maps'; + $this->request = $this->getMockBuilder('\OCP\IRequest') + ->disableOriginalConstructor() + ->getMock(); + $this->contacts = $this->getMockBuilder('OCP\Contacts\IManager') + ->disableOriginalConstructor() + ->getMock(); + + $urlGenerator = $c->getServer()->getURLGenerator(); + + $this->contactsManager = $c->query(IServerContainer::class)->getContactsManager(); + $this->cm = $c->query(ContactsManager::class); + $this->cm->setupContactsProvider($this->contactsManager, 'test', $urlGenerator); + + $this->app = new Application(); + $this->container = $this->app->getContainer(); + $c = $this->container; + $this->config = $c->query(IServerContainer::class)->getConfig(); + + $this->appData = $this->getMockBuilder('\OCP\Files\IAppData') + ->disableOriginalConstructor() + ->getMock(); + + $this->addressService = new AddressService( + $c->query(IServerContainer::class)->getMemCacheFactory(), + $c->query(IServerContainer::class)->getLogger(), + $c->query(IServerContainer::class)->getJobList(), + $this->appData, + $c->query(IServerContainer::class)->query(\OCP\IDBConnection::class) + ); + + //$this->userPrincipalBackend = new Principal( + // $c->getServer()->getUserManager(), + // $c->getServer()->getGroupManager(), + // $c->getServer()->getShareManager(), + // \OC::$server->getUserSession(), + // $c->query(IServerContainer::class)->getConfig(), + // \OC::$server->getAppManager() + //); + $this->userPrincipalBackend = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal') + ->disableOriginalConstructor() + ->getMock(); + + $this->cdBackend = $c->query(IServerContainer::class)->query(CardDavBackend::class); $this->root = $c->query(IServerContainer::class)->getRootFolder(); $this->mapFolder = $this->createMapFolder(); - $this->contactsController = new ContactsController( + $this->contactsController = new ContactsController( $this->appName, $c->query(IServerContainer::class)->getLogger(), $this->request, @@ -138,33 +132,33 @@ protected function setUp(): void { $c->query(IServerContainer::class)->getAvatarManager(), $this->root, $urlGenerator); - //$this->contactsController = $this->getMockBuilder('OCA\Maps\Controller\ContactsController') - // ->disableOriginalConstructor() - // ->getMock(); - - $this->contactsController2 = new ContactsController( - $this->appName, - $c->query(IServerContainer::class)->getLogger(), - $this->request, - $c->query(IServerContainer::class)->query(\OCP\IDBConnection::class), - $this->contactsManager, - $this->addressService, - 'test2', - $this->cdBackend, - $c->query(IServerContainer::class)->getAvatarManager(), + //$this->contactsController = $this->getMockBuilder('OCA\Maps\Controller\ContactsController') + // ->disableOriginalConstructor() + // ->getMock(); + + $this->contactsController2 = new ContactsController( + $this->appName, + $c->query(IServerContainer::class)->getLogger(), + $this->request, + $c->query(IServerContainer::class)->query(\OCP\IDBConnection::class), + $this->contactsManager, + $this->addressService, + 'test2', + $this->cdBackend, + $c->query(IServerContainer::class)->getAvatarManager(), $this->root, $urlGenerator - ); + ); - $this->utilsController = new UtilsController( - $this->appName, - $this->request, - $c->query(IServerContainer::class)->getConfig(), - $c->getServer()->getAppManager(), + $this->utilsController = new UtilsController( + $this->appName, + $this->request, + $c->query(IServerContainer::class)->getConfig(), + $c->getServer()->getAppManager(), $this->root, - 'test' - ); - } + 'test' + ); + } private function createMapFolder() { $userFolder = $this->root->getUserFolder('test'); @@ -175,26 +169,26 @@ private function createMapFolder() { } } - public static function tearDownAfterClass(): void { - } - - protected function tearDown(): void { - // in case there was a failure and something was not deleted - } - - public function testAddContact() { - $c = $this->container; - //$this->contacts->createOrUpdate() - //var_dump($this->contactsManager->isEnabled()); - // TODO understand why this only returns system address book - //var_dump($this->contactsManager->getUserAddressBooks()); - - $resp = $this->contactsController->getContacts(); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - //var_dump($data); - } + public static function tearDownAfterClass(): void { + } + + protected function tearDown(): void { + // in case there was a failure and something was not deleted + } + + public function testAddContact() { + $c = $this->container; + //$this->contacts->createOrUpdate() + //var_dump($this->contactsManager->isEnabled()); + // TODO understand why this only returns system address book + //var_dump($this->contactsManager->getUserAddressBooks()); + + $resp = $this->contactsController->getContacts(); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + //var_dump($data); + } public function testAddContactMyMap() { $c = $this->container; diff --git a/tests/Unit/Controller/DevicesApiControllerTest.php b/tests/Unit/Controller/DevicesApiControllerTest.php index 5fe28c899..519011359 100644 --- a/tests/Unit/Controller/DevicesApiControllerTest.php +++ b/tests/Unit/Controller/DevicesApiControllerTest.php @@ -11,394 +11,391 @@ namespace OCA\Maps\Controller; -use OCP\Files\IRootFolder; -use \OCP\IServerContainer; -use \OCA\Maps\AppInfo\Application; -use \OCA\Maps\Service\DevicesService; -use OCP\AppFramework\Http\TemplateResponse; - +use OCA\Maps\AppInfo\Application; +use OCA\Maps\Service\DevicesService; +use OCP\IServerContainer; class DevicesApiControllerTest extends \PHPUnit\Framework\TestCase { - private $appName; - private $request; - private $contacts; + private $appName; + private $request; + private $contacts; - private $container; - private $config; - private $app; + private $container; + private $config; + private $app; - private $devicesApiController; - private $devicesApiController2; - private $utilsController; + private $devicesApiController; + private $devicesApiController2; + private $utilsController; private $root; - public static function setUpBeforeClass(): void { - $app = new Application(); - $c = $app->getContainer(); - - $user = $c->getServer()->getUserManager()->get('test'); - $user2 = $c->getServer()->getUserManager()->get('test2'); - $user3 = $c->getServer()->getUserManager()->get('test3'); - $group = $c->getServer()->getGroupManager()->get('group1test'); - $group2 = $c->getServer()->getGroupManager()->get('group2test'); - - // CREATE DUMMY USERS - if ($user === null) { - $u1 = $c->getServer()->getUserManager()->createUser('test', 'tatotitoTUTU'); - $u1->setEMailAddress('toto@toto.net'); - } - if ($user2 === null) { - $u2 = $c->getServer()->getUserManager()->createUser('test2', 'plopinoulala000'); - } - if ($user2 === null) { - $u3 = $c->getServer()->getUserManager()->createUser('test3', 'yeyeahPASSPASS'); - } - if ($group === null) { - $c->getServer()->getGroupManager()->createGroup('group1test'); - $u1 = $c->getServer()->getUserManager()->get('test'); - $c->getServer()->getGroupManager()->get('group1test')->addUser($u1); - } - if ($group2 === null) { - $c->getServer()->getGroupManager()->createGroup('group2test'); - $u2 = $c->getServer()->getUserManager()->get('test2'); - $c->getServer()->getGroupManager()->get('group2test')->addUser($u2); - } - } - - protected function setUp(): void { - $this->appName = 'maps'; - $this->request = $this->getMockBuilder('\OCP\IRequest') - ->disableOriginalConstructor() - ->getMock(); - $this->contacts = $this->getMockBuilder('OCP\Contacts\IManager') - ->disableOriginalConstructor() - ->getMock(); - - $this->app = new Application(); - $this->container = $this->app->getContainer(); - $c = $this->container; - $this->config = $c->query(IServerContainer::class)->getConfig(); + public static function setUpBeforeClass(): void { + $app = new Application(); + $c = $app->getContainer(); + + $user = $c->getServer()->getUserManager()->get('test'); + $user2 = $c->getServer()->getUserManager()->get('test2'); + $user3 = $c->getServer()->getUserManager()->get('test3'); + $group = $c->getServer()->getGroupManager()->get('group1test'); + $group2 = $c->getServer()->getGroupManager()->get('group2test'); + + // CREATE DUMMY USERS + if ($user === null) { + $u1 = $c->getServer()->getUserManager()->createUser('test', 'tatotitoTUTU'); + $u1->setEMailAddress('toto@toto.net'); + } + if ($user2 === null) { + $u2 = $c->getServer()->getUserManager()->createUser('test2', 'plopinoulala000'); + } + if ($user2 === null) { + $u3 = $c->getServer()->getUserManager()->createUser('test3', 'yeyeahPASSPASS'); + } + if ($group === null) { + $c->getServer()->getGroupManager()->createGroup('group1test'); + $u1 = $c->getServer()->getUserManager()->get('test'); + $c->getServer()->getGroupManager()->get('group1test')->addUser($u1); + } + if ($group2 === null) { + $c->getServer()->getGroupManager()->createGroup('group2test'); + $u2 = $c->getServer()->getUserManager()->get('test2'); + $c->getServer()->getGroupManager()->get('group2test')->addUser($u2); + } + } + + protected function setUp(): void { + $this->appName = 'maps'; + $this->request = $this->getMockBuilder('\OCP\IRequest') + ->disableOriginalConstructor() + ->getMock(); + $this->contacts = $this->getMockBuilder('OCP\Contacts\IManager') + ->disableOriginalConstructor() + ->getMock(); + + $this->app = new Application(); + $this->container = $this->app->getContainer(); + $c = $this->container; + $this->config = $c->query(IServerContainer::class)->getConfig(); $this->root = $c->query(IServerContainer::class)->getRootFolder(); - $this->devicesApiController = new DevicesApiController( - $this->appName, - $this->request, - $c->query(IServerContainer::class), - $c->query(IServerContainer::class)->getConfig(), - $c->getServer()->getShareManager(), - $c->getServer()->getAppManager(), - $c->getServer()->getUserManager(), - $c->getServer()->getGroupManager(), - $c->query(IServerContainer::class)->getL10N($c->query('AppName')), - $c->query(IServerContainer::class)->getLogger(), - $c->query(DevicesService::class), - 'test' - ); - - $this->devicesApiController2 = new DevicesApiController( - $this->appName, - $this->request, - $c->query(IServerContainer::class), - $c->query(IServerContainer::class)->getConfig(), - $c->getServer()->getShareManager(), - $c->getServer()->getAppManager(), - $c->getServer()->getUserManager(), - $c->getServer()->getGroupManager(), - $c->query(IServerContainer::class)->getL10N($c->query('AppName')), - $c->query(IServerContainer::class)->getLogger(), - $c->query(DevicesService::class), - 'test2' - ); - - $this->utilsController = new UtilsController( - $this->appName, - $this->request, - $c->query(IServerContainer::class)->getConfig(), - $c->getServer()->getAppManager(), + $this->devicesApiController = new DevicesApiController( + $this->appName, + $this->request, + $c->query(IServerContainer::class), + $c->query(IServerContainer::class)->getConfig(), + $c->getServer()->getShareManager(), + $c->getServer()->getAppManager(), + $c->getServer()->getUserManager(), + $c->getServer()->getGroupManager(), + $c->query(IServerContainer::class)->getL10N($c->query('AppName')), + $c->query(IServerContainer::class)->getLogger(), + $c->query(DevicesService::class), + 'test' + ); + + $this->devicesApiController2 = new DevicesApiController( + $this->appName, + $this->request, + $c->query(IServerContainer::class), + $c->query(IServerContainer::class)->getConfig(), + $c->getServer()->getShareManager(), + $c->getServer()->getAppManager(), + $c->getServer()->getUserManager(), + $c->getServer()->getGroupManager(), + $c->query(IServerContainer::class)->getL10N($c->query('AppName')), + $c->query(IServerContainer::class)->getLogger(), + $c->query(DevicesService::class), + 'test2' + ); + + $this->utilsController = new UtilsController( + $this->appName, + $this->request, + $c->query(IServerContainer::class)->getConfig(), + $c->getServer()->getAppManager(), $this->root, - 'test' - ); - - // delete - $resp = $this->devicesApiController->getDevices('1.0'); - $data = $resp->getData(); - foreach ($data as $device) { - $resp = $this->devicesApiController->deleteDevice($device['id']); - } - } - - public static function tearDownAfterClass(): void { - } - - protected function tearDown(): void { - // in case there was a failure and something was not deleted - } - - public function testAddPoints() { - $resp = $this->devicesApiController->getDevices('1.0'); - $data = $resp->getData(); - foreach ($data as $device) { - $resp = $this->devicesApiController->deleteDevice($device['id']); - } - - // delete device that does not exist - $resp = $this->devicesApiController->deleteDevice(0); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('No such device', $data); - - // correct values - $resp = $this->devicesApiController->addDevicePoint('1.0', 1.1, 2.2, 12345, 'testDevice', 1000, 99, 50); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $deviceId = $data['deviceId']; - $pointId = $data['pointId']; - - $_SERVER['HTTP_USER_AGENT'] = 'testBrowser'; - $ts = (new \DateTime())->getTimestamp(); - $resp = $this->devicesApiController->addDevicePoint('1.0', 1.2, 2.3, null, null, 1001, 100, 5); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $deviceId2 = $data['deviceId']; - $pointId2 = $data['pointId']; - // test user agent is correct - $resp = $this->devicesApiController->getDevices('1.0'); - $data = $resp->getData(); - $d2Found = false; - foreach ($data as $device) { - if ($device['id'] === $deviceId2) { - $this->assertEquals('testBrowser', $device['user_agent']); - $d2Found = true; - } - } - $this->assertEquals(true, $d2Found); - - // This happens with a request such as /api/1.0/devices?lat=1.1&lng=2.2×tamp=&user_agent=testDevice&altitude=&battery=&accuracy= - $resp = $this->devicesApiController->addDevicePoint('1.0', 1.1, 2.2, '', 'testDevice', '', '', ''); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $deviceId3 = $data['deviceId']; - $pointId3 = $data['pointId']; - - // test point values - $resp = $this->devicesApiController->getDevicePoints($deviceId2); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals(true, count($data) === 1); - $this->assertEquals(true, $data[0]['timestamp'] >= $ts); - - // invalid values - $resp = $this->devicesApiController->addDevicePoint('1.0', 'aaa', 2.2, 12345, 'testDevice', 1000, 99, 50); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('Invalid values', $data); - - $resp = $this->devicesApiController->addDevicePoint('1.0', 1.1, 'aaa', 12345, 'testDevice', 1000, 99, 50); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('Invalid values', $data); - } - - public function testEditDevice() { - $resp = $this->devicesApiController->getDevices('1.0'); - $data = $resp->getData(); - foreach ($data as $device) { - $resp = $this->devicesApiController->deleteDevice($device['id']); - } - - $resp = $this->devicesApiController->addDevicePoint('1.0', 1.1, 2.2, 12345, 'testDevice', 1000, 99, 50); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $deviceId = $data['deviceId']; - $pointId = $data['pointId']; - - $resp = $this->devicesApiController->editDevice($deviceId, '#001122'); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals('#001122', $data['color']); - - $resp = $this->devicesApiController->editDevice(0, '#001122'); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - - $resp = $this->devicesApiController->editDevice($deviceId, ''); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - } - - //public function testImportExportDevices() { - // $resp = $this->devicesApiController->getDevices('1.0'); - // $data = $resp->getData(); - // foreach ($data as $device) { - // $resp = $this->devicesApiController->deleteDevice($device['id']); - // } - - // $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); - // $content1 = file_get_contents('tests/test_files/devicesOk.gpx'); - // $userfolder->newFile('devicesOk.gpx')->putContent($content1); - - // $resp = $this->devicesApiController->importDevices('/devicesOk.gpx'); - // $status = $resp->getStatus(); - // $this->assertEquals(200, $status); - // $data = $resp->getData(); - // $this->assertEquals(2, $data); - - // $resp = $this->devicesApiController->importDevices('/doesNotExist.gpx'); - // $status = $resp->getStatus(); - // $this->assertEquals(400, $status); - // $data = $resp->getData(); - // $this->assertEquals('File does not exist', $data); - - // $resp = $this->devicesApiController->importDevices('/nc.jpg'); - // $status = $resp->getStatus(); - // $this->assertEquals(400, $status); - - // $resp = $this->devicesApiController->importDevices('/Maps'); - // $status = $resp->getStatus(); - // $this->assertEquals(400, $status); - - // // get ids - // $devices = []; - // $resp = $this->devicesApiController->getDevices('1.0'); - // $data = $resp->getData(); - // foreach ($data as $device) { - // $id = $device['id']; - // $devices[$id] = $device; - // } - // // get number of points - // foreach ($devices as $id=>$device) { - // $resp = $this->devicesApiController->getDevicePoints($id); - // $status = $resp->getStatus(); - // $this->assertEquals(200, $status); - // $data = $resp->getData(); - // $devices[$id]['nbPoints'] = count($data); - // } - - // // export and compare - // $ids = array_keys($devices); - // $resp = $this->devicesApiController->exportDevices($ids, null, null, true); - // $status = $resp->getStatus(); - // $this->assertEquals(200, $status); - // $exportPath = $resp->getData(); - // $this->assertEquals(true, $userfolder->nodeExists($exportPath)); - - // // parse xml and compare number of devices and points - // $xmLData = $userfolder->get($exportPath)->getContent(); - // $xml = simplexml_load_string($xmLData); - // $trks = $xml->trk; - // // number of devices - // $this->assertEquals(count($ids), count($trks)); - // $pointCountExport = []; - // // count exported points per device - // foreach ($trks as $trk) { - // $name = (string)$trk->name[0]; - // $pointCountExport[$name] = count($trk->trkseg[0]->trkpt); - // } - // // check that it matches the data in the DB - // foreach ($devices as $id => $device) { - // $this->assertEquals($device['nbPoints'], $pointCountExport[$device['user_agent']]); - // } - - // // export error - // $resp = $this->devicesApiController->exportDevices(null, null, null, true); - // $status = $resp->getStatus(); - // $this->assertEquals(400, $status); - // $data = $resp->getData(); - // $this->assertEquals('No device to export', $data); - - // $userfolder->get('/Maps')->delete(); - // $userfolder->newFile('Maps')->putContent('dummy content'); - // $resp = $this->devicesApiController->exportDevices($ids, null, null, true); - // $status = $resp->getStatus(); - // $this->assertEquals(400, $status); - // $data = $resp->getData(); - // $this->assertEquals('/Maps is not a directory', $data); - // $userfolder->get('/Maps')->delete(); - - // // delete all points - // $resp = $this->devicesApiController->getDevices('1.0'); - // $data = $resp->getData(); - // foreach ($data as $device) { - // $resp = $this->devicesApiController->deleteDevice($device['id']); - // } - - // // and then try to export - // $resp = $this->devicesApiController->exportDevices($ids, null, null, true); - // $status = $resp->getStatus(); - // $this->assertEquals(400, $status); - // $data = $resp->getData(); - // $this->assertEquals('Nothing to export', $data); - //} - - public function testEditDevices() { - $this->assertEquals(true, 1==1); - //// valid edition - //$resp = $this->favoritesController->addFavorite('a', 3.1, 4.1, 'cat1', null, null); - //$favId = $resp->getData()['id']; - - //$resp = $this->favoritesController->editFavorite($favId, 'aa', 3.2, 4.2, 'cat2', 'comment', 'ext'); - //$status = $resp->getStatus(); - //$this->assertEquals(200, $status); - //$data = $resp->getData(); - //$this->assertEquals($favId, $data['id']); - - //$resp = $this->favoritesController->getFavorites(); - //$favs = $resp->getData(); - //$seen = false; - //foreach ($favs as $fav) { - // if ($fav['id'] === $favId) { - // $seen = true; - // $this->assertEquals('aa', $fav['name']); - // $this->assertEquals(3.2, $fav['lat']); - // $this->assertEquals(4.2, $fav['lng']); - // $this->assertEquals('cat2', $fav['category']); - // $this->assertEquals('comment', $fav['comment']); - // $this->assertEquals('ext', $fav['extensions']); - // } - //} - //$this->assertEquals(true, $seen); - - //// invalid edition - //$resp = $this->favoritesController->editFavorite($favId, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); - //$status = $resp->getStatus(); - //$this->assertEquals(400, $status); - //$data = $resp->getData(); - //$this->assertEquals('invalid values', $data); - - //$resp = $this->favoritesController->editFavorite(-1, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); - //$this->assertEquals(400, $status); - //$data = $resp->getData(); - //$this->assertEquals('No such favorite', $data); - - //// rename category - //$resp = $this->favoritesController->addFavorite('b', 3.1, 4.2, 'cat1', null, null); - //$resp = $this->favoritesController->addFavorite('one', 3.1, 4.2, 'cat2', null, null); - - //$resp = $this->favoritesController->renameCategories(['cat1'], 'cat1RENAMED'); - //$status = $resp->getStatus(); - //$this->assertEquals(200, $status); - //$data = $resp->getData(); - //$this->assertEquals('RENAMED', $data); - //// check if renaming worked - //$resp = $this->favoritesController->getFavorites(); - //$favs = $resp->getData(); - //$seen = false; - //foreach ($favs as $fav) { - // if ($fav['name'] === 'b') { - // $seen = true; - // $this->assertEquals('cat1RENAMED', $fav['category']); - // } - //} - //$this->assertEquals(true, $seen); - } + 'test' + ); + + // delete + $resp = $this->devicesApiController->getDevices('1.0'); + $data = $resp->getData(); + foreach ($data as $device) { + $resp = $this->devicesApiController->deleteDevice($device['id']); + } + } + + public static function tearDownAfterClass(): void { + } + + protected function tearDown(): void { + // in case there was a failure and something was not deleted + } + + public function testAddPoints() { + $resp = $this->devicesApiController->getDevices('1.0'); + $data = $resp->getData(); + foreach ($data as $device) { + $resp = $this->devicesApiController->deleteDevice($device['id']); + } + + // delete device that does not exist + $resp = $this->devicesApiController->deleteDevice(0); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('No such device', $data); + + // correct values + $resp = $this->devicesApiController->addDevicePoint('1.0', 1.1, 2.2, 12345, 'testDevice', 1000, 99, 50); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $deviceId = $data['deviceId']; + $pointId = $data['pointId']; + + $_SERVER['HTTP_USER_AGENT'] = 'testBrowser'; + $ts = (new \DateTime())->getTimestamp(); + $resp = $this->devicesApiController->addDevicePoint('1.0', 1.2, 2.3, null, null, 1001, 100, 5); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $deviceId2 = $data['deviceId']; + $pointId2 = $data['pointId']; + // test user agent is correct + $resp = $this->devicesApiController->getDevices('1.0'); + $data = $resp->getData(); + $d2Found = false; + foreach ($data as $device) { + if ($device['id'] === $deviceId2) { + $this->assertEquals('testBrowser', $device['user_agent']); + $d2Found = true; + } + } + $this->assertEquals(true, $d2Found); + + // This happens with a request such as /api/1.0/devices?lat=1.1&lng=2.2×tamp=&user_agent=testDevice&altitude=&battery=&accuracy= + $resp = $this->devicesApiController->addDevicePoint('1.0', 1.1, 2.2, '', 'testDevice', '', '', ''); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $deviceId3 = $data['deviceId']; + $pointId3 = $data['pointId']; + + // test point values + $resp = $this->devicesApiController->getDevicePoints($deviceId2); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals(true, count($data) === 1); + $this->assertEquals(true, $data[0]['timestamp'] >= $ts); + + // invalid values + $resp = $this->devicesApiController->addDevicePoint('1.0', 'aaa', 2.2, 12345, 'testDevice', 1000, 99, 50); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('Invalid values', $data); + + $resp = $this->devicesApiController->addDevicePoint('1.0', 1.1, 'aaa', 12345, 'testDevice', 1000, 99, 50); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('Invalid values', $data); + } + + public function testEditDevice() { + $resp = $this->devicesApiController->getDevices('1.0'); + $data = $resp->getData(); + foreach ($data as $device) { + $resp = $this->devicesApiController->deleteDevice($device['id']); + } + + $resp = $this->devicesApiController->addDevicePoint('1.0', 1.1, 2.2, 12345, 'testDevice', 1000, 99, 50); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $deviceId = $data['deviceId']; + $pointId = $data['pointId']; + + $resp = $this->devicesApiController->editDevice($deviceId, '#001122'); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals('#001122', $data['color']); + + $resp = $this->devicesApiController->editDevice(0, '#001122'); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + + $resp = $this->devicesApiController->editDevice($deviceId, ''); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + } + + //public function testImportExportDevices() { + // $resp = $this->devicesApiController->getDevices('1.0'); + // $data = $resp->getData(); + // foreach ($data as $device) { + // $resp = $this->devicesApiController->deleteDevice($device['id']); + // } + + // $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); + // $content1 = file_get_contents('tests/test_files/devicesOk.gpx'); + // $userfolder->newFile('devicesOk.gpx')->putContent($content1); + + // $resp = $this->devicesApiController->importDevices('/devicesOk.gpx'); + // $status = $resp->getStatus(); + // $this->assertEquals(200, $status); + // $data = $resp->getData(); + // $this->assertEquals(2, $data); + + // $resp = $this->devicesApiController->importDevices('/doesNotExist.gpx'); + // $status = $resp->getStatus(); + // $this->assertEquals(400, $status); + // $data = $resp->getData(); + // $this->assertEquals('File does not exist', $data); + + // $resp = $this->devicesApiController->importDevices('/nc.jpg'); + // $status = $resp->getStatus(); + // $this->assertEquals(400, $status); + + // $resp = $this->devicesApiController->importDevices('/Maps'); + // $status = $resp->getStatus(); + // $this->assertEquals(400, $status); + + // // get ids + // $devices = []; + // $resp = $this->devicesApiController->getDevices('1.0'); + // $data = $resp->getData(); + // foreach ($data as $device) { + // $id = $device['id']; + // $devices[$id] = $device; + // } + // // get number of points + // foreach ($devices as $id=>$device) { + // $resp = $this->devicesApiController->getDevicePoints($id); + // $status = $resp->getStatus(); + // $this->assertEquals(200, $status); + // $data = $resp->getData(); + // $devices[$id]['nbPoints'] = count($data); + // } + + // // export and compare + // $ids = array_keys($devices); + // $resp = $this->devicesApiController->exportDevices($ids, null, null, true); + // $status = $resp->getStatus(); + // $this->assertEquals(200, $status); + // $exportPath = $resp->getData(); + // $this->assertEquals(true, $userfolder->nodeExists($exportPath)); + + // // parse xml and compare number of devices and points + // $xmLData = $userfolder->get($exportPath)->getContent(); + // $xml = simplexml_load_string($xmLData); + // $trks = $xml->trk; + // // number of devices + // $this->assertEquals(count($ids), count($trks)); + // $pointCountExport = []; + // // count exported points per device + // foreach ($trks as $trk) { + // $name = (string)$trk->name[0]; + // $pointCountExport[$name] = count($trk->trkseg[0]->trkpt); + // } + // // check that it matches the data in the DB + // foreach ($devices as $id => $device) { + // $this->assertEquals($device['nbPoints'], $pointCountExport[$device['user_agent']]); + // } + + // // export error + // $resp = $this->devicesApiController->exportDevices(null, null, null, true); + // $status = $resp->getStatus(); + // $this->assertEquals(400, $status); + // $data = $resp->getData(); + // $this->assertEquals('No device to export', $data); + + // $userfolder->get('/Maps')->delete(); + // $userfolder->newFile('Maps')->putContent('dummy content'); + // $resp = $this->devicesApiController->exportDevices($ids, null, null, true); + // $status = $resp->getStatus(); + // $this->assertEquals(400, $status); + // $data = $resp->getData(); + // $this->assertEquals('/Maps is not a directory', $data); + // $userfolder->get('/Maps')->delete(); + + // // delete all points + // $resp = $this->devicesApiController->getDevices('1.0'); + // $data = $resp->getData(); + // foreach ($data as $device) { + // $resp = $this->devicesApiController->deleteDevice($device['id']); + // } + + // // and then try to export + // $resp = $this->devicesApiController->exportDevices($ids, null, null, true); + // $status = $resp->getStatus(); + // $this->assertEquals(400, $status); + // $data = $resp->getData(); + // $this->assertEquals('Nothing to export', $data); + //} + + public function testEditDevices() { + $this->assertEquals(true, 1 == 1); + //// valid edition + //$resp = $this->favoritesController->addFavorite('a', 3.1, 4.1, 'cat1', null, null); + //$favId = $resp->getData()['id']; + + //$resp = $this->favoritesController->editFavorite($favId, 'aa', 3.2, 4.2, 'cat2', 'comment', 'ext'); + //$status = $resp->getStatus(); + //$this->assertEquals(200, $status); + //$data = $resp->getData(); + //$this->assertEquals($favId, $data['id']); + + //$resp = $this->favoritesController->getFavorites(); + //$favs = $resp->getData(); + //$seen = false; + //foreach ($favs as $fav) { + // if ($fav['id'] === $favId) { + // $seen = true; + // $this->assertEquals('aa', $fav['name']); + // $this->assertEquals(3.2, $fav['lat']); + // $this->assertEquals(4.2, $fav['lng']); + // $this->assertEquals('cat2', $fav['category']); + // $this->assertEquals('comment', $fav['comment']); + // $this->assertEquals('ext', $fav['extensions']); + // } + //} + //$this->assertEquals(true, $seen); + + //// invalid edition + //$resp = $this->favoritesController->editFavorite($favId, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); + //$status = $resp->getStatus(); + //$this->assertEquals(400, $status); + //$data = $resp->getData(); + //$this->assertEquals('invalid values', $data); + + //$resp = $this->favoritesController->editFavorite(-1, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); + //$this->assertEquals(400, $status); + //$data = $resp->getData(); + //$this->assertEquals('No such favorite', $data); + + //// rename category + //$resp = $this->favoritesController->addFavorite('b', 3.1, 4.2, 'cat1', null, null); + //$resp = $this->favoritesController->addFavorite('one', 3.1, 4.2, 'cat2', null, null); + + //$resp = $this->favoritesController->renameCategories(['cat1'], 'cat1RENAMED'); + //$status = $resp->getStatus(); + //$this->assertEquals(200, $status); + //$data = $resp->getData(); + //$this->assertEquals('RENAMED', $data); + //// check if renaming worked + //$resp = $this->favoritesController->getFavorites(); + //$favs = $resp->getData(); + //$seen = false; + //foreach ($favs as $fav) { + // if ($fav['name'] === 'b') { + // $seen = true; + // $this->assertEquals('cat1RENAMED', $fav['category']); + // } + //} + //$this->assertEquals(true, $seen); + } } diff --git a/tests/Unit/Controller/DevicesControllerTest.php b/tests/Unit/Controller/DevicesControllerTest.php index 63b154f71..15e120f85 100644 --- a/tests/Unit/Controller/DevicesControllerTest.php +++ b/tests/Unit/Controller/DevicesControllerTest.php @@ -11,423 +11,421 @@ namespace OCA\Maps\Controller; +use OCA\Maps\AppInfo\Application; use OCA\Maps\DB\DeviceShareMapper; +use OCA\Maps\Service\DevicesService; use OCP\Files\IRootFolder; -use \OCP\IServerContainer; -use \OCA\Maps\AppInfo\Application; -use \OCA\Maps\Service\DevicesService; -use OCP\AppFramework\Http\TemplateResponse; - +use OCP\IServerContainer; class DevicesControllerTest extends \PHPUnit\Framework\TestCase { - private $appName; - private $request; - private $contacts; + private $appName; + private $request; + private $contacts; - private $container; - private $config; - private $app; + private $container; + private $config; + private $app; - private $devicesController; - private $devicesController2; - private $utilsController; + private $devicesController; + private $devicesController2; + private $utilsController; private $root; - public static function setUpBeforeClass(): void { - $app = new Application(); - $c = $app->getContainer(); - - $user = $c->getServer()->getUserManager()->get('test'); - $user2 = $c->getServer()->getUserManager()->get('test2'); - $user3 = $c->getServer()->getUserManager()->get('test3'); - $group = $c->getServer()->getGroupManager()->get('group1test'); - $group2 = $c->getServer()->getGroupManager()->get('group2test'); - - // CREATE DUMMY USERS - if ($user === null) { - $u1 = $c->getServer()->getUserManager()->createUser('test', 'tatotitoTUTU'); - $u1->setEMailAddress('toto@toto.net'); - } - if ($user2 === null) { - $u2 = $c->getServer()->getUserManager()->createUser('test2', 'plopinoulala000'); - } - if ($user2 === null) { - $u3 = $c->getServer()->getUserManager()->createUser('test3', 'yeyeahPASSPASS'); - } - if ($group === null) { - $c->getServer()->getGroupManager()->createGroup('group1test'); - $u1 = $c->getServer()->getUserManager()->get('test'); - $c->getServer()->getGroupManager()->get('group1test')->addUser($u1); - } - if ($group2 === null) { - $c->getServer()->getGroupManager()->createGroup('group2test'); - $u2 = $c->getServer()->getUserManager()->get('test2'); - $c->getServer()->getGroupManager()->get('group2test')->addUser($u2); - } - } - - protected function setUp(): void { - $this->appName = 'maps'; - $this->request = $this->getMockBuilder('\OCP\IRequest') - ->disableOriginalConstructor() - ->getMock(); - $this->contacts = $this->getMockBuilder('OCP\Contacts\IManager') - ->disableOriginalConstructor() - ->getMock(); - - $this->app = new Application(); - $this->container = $this->app->getContainer(); - $c = $this->container; - $this->config = $c->query(IServerContainer::class)->getConfig(); + public static function setUpBeforeClass(): void { + $app = new Application(); + $c = $app->getContainer(); + + $user = $c->getServer()->getUserManager()->get('test'); + $user2 = $c->getServer()->getUserManager()->get('test2'); + $user3 = $c->getServer()->getUserManager()->get('test3'); + $group = $c->getServer()->getGroupManager()->get('group1test'); + $group2 = $c->getServer()->getGroupManager()->get('group2test'); + + // CREATE DUMMY USERS + if ($user === null) { + $u1 = $c->getServer()->getUserManager()->createUser('test', 'tatotitoTUTU'); + $u1->setEMailAddress('toto@toto.net'); + } + if ($user2 === null) { + $u2 = $c->getServer()->getUserManager()->createUser('test2', 'plopinoulala000'); + } + if ($user2 === null) { + $u3 = $c->getServer()->getUserManager()->createUser('test3', 'yeyeahPASSPASS'); + } + if ($group === null) { + $c->getServer()->getGroupManager()->createGroup('group1test'); + $u1 = $c->getServer()->getUserManager()->get('test'); + $c->getServer()->getGroupManager()->get('group1test')->addUser($u1); + } + if ($group2 === null) { + $c->getServer()->getGroupManager()->createGroup('group2test'); + $u2 = $c->getServer()->getUserManager()->get('test2'); + $c->getServer()->getGroupManager()->get('group2test')->addUser($u2); + } + } + + protected function setUp(): void { + $this->appName = 'maps'; + $this->request = $this->getMockBuilder('\OCP\IRequest') + ->disableOriginalConstructor() + ->getMock(); + $this->contacts = $this->getMockBuilder('OCP\Contacts\IManager') + ->disableOriginalConstructor() + ->getMock(); + + $this->app = new Application(); + $this->container = $this->app->getContainer(); + $c = $this->container; + $this->config = $c->query(IServerContainer::class)->getConfig(); $this->root = $c->query(IServerContainer::class)->getRootFolder(); - $this->devicesController = new DevicesController( - $this->appName, - $this->request, - $c->query(IServerContainer::class), - $c->query(IServerContainer::class)->getConfig(), - $c->getServer()->getShareManager(), - $c->getServer()->getAppManager(), - $c->getServer()->getUserManager(), - $c->getServer()->getGroupManager(), - $c->query(IServerContainer::class)->getL10N($c->query('AppName')), - $c->query(IServerContainer::class)->getLogger(), - $c->query(DevicesService::class), + $this->devicesController = new DevicesController( + $this->appName, + $this->request, + $c->query(IServerContainer::class), + $c->query(IServerContainer::class)->getConfig(), + $c->getServer()->getShareManager(), + $c->getServer()->getAppManager(), + $c->getServer()->getUserManager(), + $c->getServer()->getGroupManager(), + $c->query(IServerContainer::class)->getL10N($c->query('AppName')), + $c->query(IServerContainer::class)->getLogger(), + $c->query(DevicesService::class), $c->query(DeviceShareMapper::class), - $c->query(IServerContainer::class)->getDateTimeZone(), + $c->query(IServerContainer::class)->getDateTimeZone(), $c->query(IRootFolder::class), - 'test' - ); - - $this->devicesController2 = new DevicesController( - $this->appName, - $this->request, - $c->query(IServerContainer::class), - $c->query(IServerContainer::class)->getConfig(), - $c->getServer()->getShareManager(), - $c->getServer()->getAppManager(), - $c->getServer()->getUserManager(), - $c->getServer()->getGroupManager(), - $c->query(IServerContainer::class)->getL10N($c->query('AppName')), - $c->query(IServerContainer::class)->getLogger(), - $c->query(DevicesService::class), + 'test' + ); + + $this->devicesController2 = new DevicesController( + $this->appName, + $this->request, + $c->query(IServerContainer::class), + $c->query(IServerContainer::class)->getConfig(), + $c->getServer()->getShareManager(), + $c->getServer()->getAppManager(), + $c->getServer()->getUserManager(), + $c->getServer()->getGroupManager(), + $c->query(IServerContainer::class)->getL10N($c->query('AppName')), + $c->query(IServerContainer::class)->getLogger(), + $c->query(DevicesService::class), $c->query(DeviceShareMapper::class), - $c->query(IServerContainer::class)->getDateTimeZone(), + $c->query(IServerContainer::class)->getDateTimeZone(), $c->query(IRootFolder::class), - 'test2' - ); - - $this->utilsController = new UtilsController( - $this->appName, - $this->request, - $c->query(IServerContainer::class)->getConfig(), - $c->getServer()->getAppManager(), + 'test2' + ); + + $this->utilsController = new UtilsController( + $this->appName, + $this->request, + $c->query(IServerContainer::class)->getConfig(), + $c->getServer()->getAppManager(), $this->root, - 'test' - ); - - // delete - $resp = $this->devicesController->getDevices(); - $data = $resp->getData(); - foreach ($data as $device) { - $resp = $this->devicesController->deleteDevice($device['id']); - } - } - - public static function tearDownAfterClass(): void { - //$app = new Application(); - //$c = $app->getContainer(); - //$user = $c->getServer()->getUserManager()->get('test'); - //$user->delete(); - //$user = $c->getServer()->getUserManager()->get('test2'); - //$user->delete(); - //$user = $c->getServer()->getUserManager()->get('test3'); - //$user->delete(); - //$c->getServer()->getGroupManager()->get('group1test')->delete(); - //$c->getServer()->getGroupManager()->get('group2test')->delete(); - } - - protected function tearDown(): void { - // in case there was a failure and something was not deleted - } - - public function testAddPoints() { - $resp = $this->devicesController->getDevices(); - $data = $resp->getData(); - foreach ($data as $device) { - $resp = $this->devicesController->deleteDevice($device['id']); - } - - // delete device that does not exist - $resp = $this->devicesController->deleteDevice(0); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('No such device', $data); - - // correct values - $resp = $this->devicesController->addDevicePoint(1.1, 2.2, 12345, 'testDevice', 1000, 99, 50); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $deviceId = $data['deviceId']; - $pointId = $data['pointId']; - - $_SERVER['HTTP_USER_AGENT'] = 'testBrowser'; - $ts = (new \DateTime())->getTimestamp(); - $resp = $this->devicesController->addDevicePoint(1.2, 2.3, null, null, 1001, 100, 5); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $deviceId2 = $data['deviceId']; - $pointId2 = $data['pointId']; - // test user agent is correct - $resp = $this->devicesController->getDevices(); - $data = $resp->getData(); - $d2Found = false; - foreach ($data as $device) { - if ($device['id'] === $deviceId2) { - $this->assertEquals('testBrowser', $device['user_agent']); - $d2Found = true; - } - } - $this->assertEquals(true, $d2Found); - - // test point values - $resp = $this->devicesController->getDevicePoints($deviceId2); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals(true, count($data) === 1); - $this->assertEquals(true, $data[0]['timestamp'] >= $ts); - - // test missing values - $resp = $this->devicesController->addDevicePoint(1.1, 2.2, 12346, 'testDevice', null, null, null); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - - $resp = $this->devicesController->addDevicePoint(1.1, 2.2, 12347, 'testDevice', '', '', ''); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - - $resp = $this->devicesController->addDevicePoint(1.1, 2.2, 12348, 'testDevice', 'a', 'b', 'c'); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - - $resp = $this->devicesController->getDevicePoints($deviceId); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals(true, count($data) === 4); - - // invalid values - $resp = $this->devicesController->addDevicePoint('aaa', 2.2, 12345, 'testDevice', 1000, 99, 50); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('Invalid values', $data); - - $resp = $this->devicesController->addDevicePoint(1.1, 'aaa', 12345, 'testDevice', 1000, 99, 50); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('Invalid values', $data); - } - - public function testEditDevice() { - $resp = $this->devicesController->getDevices(); - $data = $resp->getData(); - foreach ($data as $device) { - $resp = $this->devicesController->deleteDevice($device['id']); - } - - $resp = $this->devicesController->addDevicePoint(1.1, 2.2, 12345, 'testDevice', 1000, 99, 50); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $deviceId = $data['deviceId']; - $pointId = $data['pointId']; - - $resp = $this->devicesController->editDevice($deviceId, '#001122', 'editedDevice'); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals('#001122', $data['color']); - $this->assertEquals('editedDevice', $data['user_agent']); - - $resp = $this->devicesController->editDevice(0, '#001122', 'editedDevice'); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - - $resp = $this->devicesController->editDevice($deviceId, '', ''); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - } - - public function testImportExportDevices() { - $resp = $this->devicesController->getDevices(); - $data = $resp->getData(); - foreach ($data as $device) { - $resp = $this->devicesController->deleteDevice($device['id']); - } - - $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); - $content1 = file_get_contents('tests/test_files/devicesOk.gpx'); - $userfolder->newFile('devicesOk.gpx')->putContent($content1); - - $resp = $this->devicesController->importDevices('/devicesOk.gpx'); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals(2, $data); - - $resp = $this->devicesController->importDevices('/doesNotExist.gpx'); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('File does not exist', $data); - - $resp = $this->devicesController->importDevices('/nc.jpg'); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - - $resp = $this->devicesController->importDevices('/Maps'); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - - // get ids - $devices = []; - $resp = $this->devicesController->getDevices(); - $data = $resp->getData(); - foreach ($data as $device) { - $id = $device['id']; - $devices[$id] = $device; - } - // get number of points - foreach ($devices as $id=>$device) { - $resp = $this->devicesController->getDevicePoints($id); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $devices[$id]['nbPoints'] = count($data); - } - - // export and compare - $ids = array_keys($devices); - $resp = $this->devicesController->exportDevices($ids, null, null, true); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $exportPath = $resp->getData(); - $this->assertEquals(true, $userfolder->nodeExists($exportPath)); - - // parse xml and compare number of devices and points - $xmLData = $userfolder->get($exportPath)->getContent(); - $xml = simplexml_load_string($xmLData); - $trks = $xml->trk; - // number of devices - $this->assertEquals(count($ids), count($trks)); - $pointCountExport = []; - // count exported points per device - foreach ($trks as $trk) { - $name = (string)$trk->name[0]; - $pointCountExport[$name] = count($trk->trkseg[0]->trkpt); - } - // check that it matches the data in the DB - foreach ($devices as $id => $device) { - $this->assertEquals($device['nbPoints'], $pointCountExport[$device['user_agent']]); - } - - // export error - $resp = $this->devicesController->exportDevices(null, null, null, true); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('No device to export', $data); - - $userfolder->get('/Maps')->delete(); - $userfolder->newFile('Maps')->putContent('dummy content'); - $resp = $this->devicesController->exportDevices($ids, null, null, true); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('/Maps is not a directory', $data); - $userfolder->get('/Maps')->delete(); - - // delete all points - $resp = $this->devicesController->getDevices(); - $data = $resp->getData(); - foreach ($data as $device) { - $resp = $this->devicesController->deleteDevice($device['id']); - } - - // and then try to export - $resp = $this->devicesController->exportDevices($ids, null, null, true); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('Nothing to export', $data); - } - - public function testEditDevices() { - $this->assertEquals(true, 1==1); - //// valid edition - //$resp = $this->favoritesController->addFavorite('a', 3.1, 4.1, 'cat1', null, null); - //$favId = $resp->getData()['id']; - - //$resp = $this->favoritesController->editFavorite($favId, 'aa', 3.2, 4.2, 'cat2', 'comment', 'ext'); - //$status = $resp->getStatus(); - //$this->assertEquals(200, $status); - //$data = $resp->getData(); - //$this->assertEquals($favId, $data['id']); - - //$resp = $this->favoritesController->getFavorites(); - //$favs = $resp->getData(); - //$seen = false; - //foreach ($favs as $fav) { - // if ($fav['id'] === $favId) { - // $seen = true; - // $this->assertEquals('aa', $fav['name']); - // $this->assertEquals(3.2, $fav['lat']); - // $this->assertEquals(4.2, $fav['lng']); - // $this->assertEquals('cat2', $fav['category']); - // $this->assertEquals('comment', $fav['comment']); - // $this->assertEquals('ext', $fav['extensions']); - // } - //} - //$this->assertEquals(true, $seen); - - //// invalid edition - //$resp = $this->favoritesController->editFavorite($favId, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); - //$status = $resp->getStatus(); - //$this->assertEquals(400, $status); - //$data = $resp->getData(); - //$this->assertEquals('invalid values', $data); - - //$resp = $this->favoritesController->editFavorite(-1, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); - //$this->assertEquals(400, $status); - //$data = $resp->getData(); - //$this->assertEquals('No such favorite', $data); - - //// rename category - //$resp = $this->favoritesController->addFavorite('b', 3.1, 4.2, 'cat1', null, null); - //$resp = $this->favoritesController->addFavorite('one', 3.1, 4.2, 'cat2', null, null); - - //$resp = $this->favoritesController->renameCategories(['cat1'], 'cat1RENAMED'); - //$status = $resp->getStatus(); - //$this->assertEquals(200, $status); - //$data = $resp->getData(); - //$this->assertEquals('RENAMED', $data); - //// check if renaming worked - //$resp = $this->favoritesController->getFavorites(); - //$favs = $resp->getData(); - //$seen = false; - //foreach ($favs as $fav) { - // if ($fav['name'] === 'b') { - // $seen = true; - // $this->assertEquals('cat1RENAMED', $fav['category']); - // } - //} - //$this->assertEquals(true, $seen); - } + 'test' + ); + + // delete + $resp = $this->devicesController->getDevices(); + $data = $resp->getData(); + foreach ($data as $device) { + $resp = $this->devicesController->deleteDevice($device['id']); + } + } + + public static function tearDownAfterClass(): void { + //$app = new Application(); + //$c = $app->getContainer(); + //$user = $c->getServer()->getUserManager()->get('test'); + //$user->delete(); + //$user = $c->getServer()->getUserManager()->get('test2'); + //$user->delete(); + //$user = $c->getServer()->getUserManager()->get('test3'); + //$user->delete(); + //$c->getServer()->getGroupManager()->get('group1test')->delete(); + //$c->getServer()->getGroupManager()->get('group2test')->delete(); + } + + protected function tearDown(): void { + // in case there was a failure and something was not deleted + } + + public function testAddPoints() { + $resp = $this->devicesController->getDevices(); + $data = $resp->getData(); + foreach ($data as $device) { + $resp = $this->devicesController->deleteDevice($device['id']); + } + + // delete device that does not exist + $resp = $this->devicesController->deleteDevice(0); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('No such device', $data); + + // correct values + $resp = $this->devicesController->addDevicePoint(1.1, 2.2, 12345, 'testDevice', 1000, 99, 50); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $deviceId = $data['deviceId']; + $pointId = $data['pointId']; + + $_SERVER['HTTP_USER_AGENT'] = 'testBrowser'; + $ts = (new \DateTime())->getTimestamp(); + $resp = $this->devicesController->addDevicePoint(1.2, 2.3, null, null, 1001, 100, 5); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $deviceId2 = $data['deviceId']; + $pointId2 = $data['pointId']; + // test user agent is correct + $resp = $this->devicesController->getDevices(); + $data = $resp->getData(); + $d2Found = false; + foreach ($data as $device) { + if ($device['id'] === $deviceId2) { + $this->assertEquals('testBrowser', $device['user_agent']); + $d2Found = true; + } + } + $this->assertEquals(true, $d2Found); + + // test point values + $resp = $this->devicesController->getDevicePoints($deviceId2); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals(true, count($data) === 1); + $this->assertEquals(true, $data[0]['timestamp'] >= $ts); + + // test missing values + $resp = $this->devicesController->addDevicePoint(1.1, 2.2, 12346, 'testDevice', null, null, null); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + + $resp = $this->devicesController->addDevicePoint(1.1, 2.2, 12347, 'testDevice', '', '', ''); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + + $resp = $this->devicesController->addDevicePoint(1.1, 2.2, 12348, 'testDevice', 'a', 'b', 'c'); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + + $resp = $this->devicesController->getDevicePoints($deviceId); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals(true, count($data) === 4); + + // invalid values + $resp = $this->devicesController->addDevicePoint('aaa', 2.2, 12345, 'testDevice', 1000, 99, 50); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('Invalid values', $data); + + $resp = $this->devicesController->addDevicePoint(1.1, 'aaa', 12345, 'testDevice', 1000, 99, 50); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('Invalid values', $data); + } + + public function testEditDevice() { + $resp = $this->devicesController->getDevices(); + $data = $resp->getData(); + foreach ($data as $device) { + $resp = $this->devicesController->deleteDevice($device['id']); + } + + $resp = $this->devicesController->addDevicePoint(1.1, 2.2, 12345, 'testDevice', 1000, 99, 50); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $deviceId = $data['deviceId']; + $pointId = $data['pointId']; + + $resp = $this->devicesController->editDevice($deviceId, '#001122', 'editedDevice'); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals('#001122', $data['color']); + $this->assertEquals('editedDevice', $data['user_agent']); + + $resp = $this->devicesController->editDevice(0, '#001122', 'editedDevice'); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + + $resp = $this->devicesController->editDevice($deviceId, '', ''); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + } + + public function testImportExportDevices() { + $resp = $this->devicesController->getDevices(); + $data = $resp->getData(); + foreach ($data as $device) { + $resp = $this->devicesController->deleteDevice($device['id']); + } + + $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); + $content1 = file_get_contents('tests/test_files/devicesOk.gpx'); + $userfolder->newFile('devicesOk.gpx')->putContent($content1); + + $resp = $this->devicesController->importDevices('/devicesOk.gpx'); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals(2, $data); + + $resp = $this->devicesController->importDevices('/doesNotExist.gpx'); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('File does not exist', $data); + + $resp = $this->devicesController->importDevices('/nc.jpg'); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + + $resp = $this->devicesController->importDevices('/Maps'); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + + // get ids + $devices = []; + $resp = $this->devicesController->getDevices(); + $data = $resp->getData(); + foreach ($data as $device) { + $id = $device['id']; + $devices[$id] = $device; + } + // get number of points + foreach ($devices as $id => $device) { + $resp = $this->devicesController->getDevicePoints($id); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $devices[$id]['nbPoints'] = count($data); + } + + // export and compare + $ids = array_keys($devices); + $resp = $this->devicesController->exportDevices($ids, null, null, true); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $exportPath = $resp->getData(); + $this->assertEquals(true, $userfolder->nodeExists($exportPath)); + + // parse xml and compare number of devices and points + $xmLData = $userfolder->get($exportPath)->getContent(); + $xml = simplexml_load_string($xmLData); + $trks = $xml->trk; + // number of devices + $this->assertEquals(count($ids), count($trks)); + $pointCountExport = []; + // count exported points per device + foreach ($trks as $trk) { + $name = (string)$trk->name[0]; + $pointCountExport[$name] = count($trk->trkseg[0]->trkpt); + } + // check that it matches the data in the DB + foreach ($devices as $id => $device) { + $this->assertEquals($device['nbPoints'], $pointCountExport[$device['user_agent']]); + } + + // export error + $resp = $this->devicesController->exportDevices(null, null, null, true); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('No device to export', $data); + + $userfolder->get('/Maps')->delete(); + $userfolder->newFile('Maps')->putContent('dummy content'); + $resp = $this->devicesController->exportDevices($ids, null, null, true); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('/Maps is not a directory', $data); + $userfolder->get('/Maps')->delete(); + + // delete all points + $resp = $this->devicesController->getDevices(); + $data = $resp->getData(); + foreach ($data as $device) { + $resp = $this->devicesController->deleteDevice($device['id']); + } + + // and then try to export + $resp = $this->devicesController->exportDevices($ids, null, null, true); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('Nothing to export', $data); + } + + public function testEditDevices() { + $this->assertEquals(true, 1 == 1); + //// valid edition + //$resp = $this->favoritesController->addFavorite('a', 3.1, 4.1, 'cat1', null, null); + //$favId = $resp->getData()['id']; + + //$resp = $this->favoritesController->editFavorite($favId, 'aa', 3.2, 4.2, 'cat2', 'comment', 'ext'); + //$status = $resp->getStatus(); + //$this->assertEquals(200, $status); + //$data = $resp->getData(); + //$this->assertEquals($favId, $data['id']); + + //$resp = $this->favoritesController->getFavorites(); + //$favs = $resp->getData(); + //$seen = false; + //foreach ($favs as $fav) { + // if ($fav['id'] === $favId) { + // $seen = true; + // $this->assertEquals('aa', $fav['name']); + // $this->assertEquals(3.2, $fav['lat']); + // $this->assertEquals(4.2, $fav['lng']); + // $this->assertEquals('cat2', $fav['category']); + // $this->assertEquals('comment', $fav['comment']); + // $this->assertEquals('ext', $fav['extensions']); + // } + //} + //$this->assertEquals(true, $seen); + + //// invalid edition + //$resp = $this->favoritesController->editFavorite($favId, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); + //$status = $resp->getStatus(); + //$this->assertEquals(400, $status); + //$data = $resp->getData(); + //$this->assertEquals('invalid values', $data); + + //$resp = $this->favoritesController->editFavorite(-1, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); + //$this->assertEquals(400, $status); + //$data = $resp->getData(); + //$this->assertEquals('No such favorite', $data); + + //// rename category + //$resp = $this->favoritesController->addFavorite('b', 3.1, 4.2, 'cat1', null, null); + //$resp = $this->favoritesController->addFavorite('one', 3.1, 4.2, 'cat2', null, null); + + //$resp = $this->favoritesController->renameCategories(['cat1'], 'cat1RENAMED'); + //$status = $resp->getStatus(); + //$this->assertEquals(200, $status); + //$data = $resp->getData(); + //$this->assertEquals('RENAMED', $data); + //// check if renaming worked + //$resp = $this->favoritesController->getFavorites(); + //$favs = $resp->getData(); + //$seen = false; + //foreach ($favs as $fav) { + // if ($fav['name'] === 'b') { + // $seen = true; + // $this->assertEquals('cat1RENAMED', $fav['category']); + // } + //} + //$this->assertEquals(true, $seen); + } } diff --git a/tests/Unit/Controller/FavoritesApiControllerTest.php b/tests/Unit/Controller/FavoritesApiControllerTest.php index e5eed8b9f..1018874a7 100644 --- a/tests/Unit/Controller/FavoritesApiControllerTest.php +++ b/tests/Unit/Controller/FavoritesApiControllerTest.php @@ -11,242 +11,233 @@ namespace OCA\Maps\Controller; -use \OCP\IServerContainer; -use \OCA\Maps\AppInfo\Application; -use \OCA\Maps\Service\FavoritesService; -use OCP\AppFramework\Http\TemplateResponse; - - -class FavoritesApiControllerTest extends \PHPUnit\Framework\TestCase -{ - private $appName; - private $request; - private $contacts; - - private $container; - private $config; - private $app; - private $root; - - private $favoritesApiController; - private $favoritesApiController2; - private $utilsController; - - public static function setUpBeforeClass(): void - { - $app = new Application(); - $c = $app->getContainer(); - - $user = $c->getServer()->getUserManager()->get('test'); - $user2 = $c->getServer()->getUserManager()->get('test2'); - $user3 = $c->getServer()->getUserManager()->get('test3'); - $group = $c->getServer()->getGroupManager()->get('group1test'); - $group2 = $c->getServer()->getGroupManager()->get('group2test'); - - // CREATE DUMMY USERS - if ($user === null) { - $u1 = $c->getServer()->getUserManager()->createUser('test', 'tatotitoTUTU'); - $u1->setEMailAddress('toto@toto.net'); - } - if ($user2 === null) { - $u2 = $c->getServer()->getUserManager()->createUser('test2', 'plopinoulala000'); - } - if ($user2 === null) { - $u3 = $c->getServer()->getUserManager()->createUser('test3', 'yeyeahPASSPASS'); - } - if ($group === null) { - $c->getServer()->getGroupManager()->createGroup('group1test'); - $u1 = $c->getServer()->getUserManager()->get('test'); - $c->getServer()->getGroupManager()->get('group1test')->addUser($u1); - } - if ($group2 === null) { - $c->getServer()->getGroupManager()->createGroup('group2test'); - $u2 = $c->getServer()->getUserManager()->get('test2'); - $c->getServer()->getGroupManager()->get('group2test')->addUser($u2); - } - } - - protected function setUp(): void - { - $this->appName = 'maps'; - $this->request = $this->getMockBuilder('\OCP\IRequest') - ->disableOriginalConstructor() - ->getMock(); - $this->contacts = $this->getMockBuilder('OCP\Contacts\IManager') - ->disableOriginalConstructor() - ->getMock(); - - $this->app = new Application(); - $this->container = $this->app->getContainer(); - $c = $this->container; - $this->config = $c->query(IServerContainer::class)->getConfig(); - $this->root = $c->query(IServerContainer::class)->getRootFolder(); - - $this->favoritesApiController = new FavoritesApiController( - $this->appName, - $this->request, - $c->query(IServerContainer::class), - $c->query(IServerContainer::class)->getConfig(), - $c->getServer()->getShareManager(), - $c->getServer()->getAppManager(), - $c->getServer()->getUserManager(), - $c->getServer()->getGroupManager(), - $c->query(IServerContainer::class)->getL10N($c->query('AppName')), - $c->query(IServerContainer::class)->getLogger(), - $c->query(FavoritesService::class), - 'test' - ); - - $this->favoritesApiController2 = new FavoritesApiController( - $this->appName, - $this->request, - $c->query(IServerContainer::class), - $c->query(IServerContainer::class)->getConfig(), - $c->getServer()->getShareManager(), - $c->getServer()->getAppManager(), - $c->getServer()->getUserManager(), - $c->getServer()->getGroupManager(), - $c->query(IServerContainer::class)->getL10N($c->query('AppName')), - $c->query(IServerContainer::class)->getLogger(), - $c->query(FavoritesService::class), - 'test2' - ); - - $this->utilsController = new UtilsController( - $this->appName, - $this->request, - $c->query(IServerContainer::class)->getConfig(), - $c->getServer()->getAppManager(), - $this->root, - 'test' - ); - } - - public static function tearDownAfterClass(): void - { - //$app = new Application(); - //$c = $app->getContainer(); - //$user = $c->getServer()->getUserManager()->get('test'); - //$user->delete(); - //$user = $c->getServer()->getUserManager()->get('test2'); - //$user->delete(); - //$user = $c->getServer()->getUserManager()->get('test3'); - //$user->delete(); - //$c->getServer()->getGroupManager()->get('group1test')->delete(); - //$c->getServer()->getGroupManager()->get('group2test')->delete(); - } - - protected function tearDown(): void - { - // in case there was a failure and something was not deleted - $resp = $this->favoritesApiController->getFavorites('1.0'); - $data = $resp->getData(); - foreach ($data as $fav) { - $resp = $this->favoritesApiController->deleteFavorite($fav['id']); - } - } - - public function testAddFavorites() - { - // correct values - $resp = $this->favoritesApiController->addFavorite('1.0', 'one', 3.1, 4.2, '', null, null); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals('one', $data['name']); - $id1 = $data['id']; - - $resp = $this->favoritesApiController->addFavorite('1.0', '', 3.1, 4.2, '', null, null); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals('', $data['name']); - $id2 = $data['id']; - - // Invalid values - $resp = $this->favoritesApiController->addFavorite('1.0', 'one', 'lat', 4.2, '', null, null); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - - $resp = $this->favoritesApiController->addFavorite('1.0', 'one', 3.1, 'lon', '', null, null); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - - // get favorites - $resp = $this->favoritesApiController->getFavorites('1.0'); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals(2, count($data)); - - //// get favorites using etag - //$etag = $resp->getEtag(); - //var_dump($etag); - //$this->request->setHeader('If-None-Match', '"'.$etag.'"'); - //$resp = $this->favoritesApiController->getFavorites('1.0'); - //$status = $resp->getStatus(); - //$this->assertEquals(200, $status); - //$data = $resp->getData(); - //$this->assertEquals(2, count($data)); - - // delete created favorites - $resp = $this->favoritesApiController->deleteFavorite($id1); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals('DELETED', $data); - - $resp = $this->favoritesApiController->deleteFavorite($id2); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals('DELETED', $data); - - // delete something that does not exist - $resp = $this->favoritesApiController->deleteFavorite($id2); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - } - - public function testEditFavorites() - { - // valid edition - $resp = $this->favoritesApiController->addFavorite('1.0', 'a', 3.1, 4.1, 'cat1', null, null); - $favId = $resp->getData()['id']; - - $resp = $this->favoritesApiController->editFavorite($favId, 'aa', 3.2, 4.2, 'cat2', 'comment', 'ext'); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals($favId, $data['id']); - - $resp = $this->favoritesApiController->getFavorites('1.0'); - $favs = $resp->getData(); - $seen = false; - foreach ($favs as $fav) { - if ($fav['id'] === $favId) { - $seen = true; - $this->assertEquals('aa', $fav['name']); - $this->assertEquals(3.2, $fav['lat']); - $this->assertEquals(4.2, $fav['lng']); - $this->assertEquals('cat2', $fav['category']); - $this->assertEquals('comment', $fav['comment']); - $this->assertEquals('ext', $fav['extensions']); - } - } - $this->assertEquals(true, $seen); - - // invalid edition - $resp = $this->favoritesApiController->editFavorite($favId, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('Invalid values', $data); - - $resp = $this->favoritesApiController->editFavorite(-1, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('No such favorite', $data); - } +use OCA\Maps\AppInfo\Application; +use OCA\Maps\Service\FavoritesService; +use OCP\IServerContainer; + +class FavoritesApiControllerTest extends \PHPUnit\Framework\TestCase { + private $appName; + private $request; + private $contacts; + + private $container; + private $config; + private $app; + private $root; + + private $favoritesApiController; + private $favoritesApiController2; + private $utilsController; + + public static function setUpBeforeClass(): void { + $app = new Application(); + $c = $app->getContainer(); + + $user = $c->getServer()->getUserManager()->get('test'); + $user2 = $c->getServer()->getUserManager()->get('test2'); + $user3 = $c->getServer()->getUserManager()->get('test3'); + $group = $c->getServer()->getGroupManager()->get('group1test'); + $group2 = $c->getServer()->getGroupManager()->get('group2test'); + + // CREATE DUMMY USERS + if ($user === null) { + $u1 = $c->getServer()->getUserManager()->createUser('test', 'tatotitoTUTU'); + $u1->setEMailAddress('toto@toto.net'); + } + if ($user2 === null) { + $u2 = $c->getServer()->getUserManager()->createUser('test2', 'plopinoulala000'); + } + if ($user2 === null) { + $u3 = $c->getServer()->getUserManager()->createUser('test3', 'yeyeahPASSPASS'); + } + if ($group === null) { + $c->getServer()->getGroupManager()->createGroup('group1test'); + $u1 = $c->getServer()->getUserManager()->get('test'); + $c->getServer()->getGroupManager()->get('group1test')->addUser($u1); + } + if ($group2 === null) { + $c->getServer()->getGroupManager()->createGroup('group2test'); + $u2 = $c->getServer()->getUserManager()->get('test2'); + $c->getServer()->getGroupManager()->get('group2test')->addUser($u2); + } + } + + protected function setUp(): void { + $this->appName = 'maps'; + $this->request = $this->getMockBuilder('\OCP\IRequest') + ->disableOriginalConstructor() + ->getMock(); + $this->contacts = $this->getMockBuilder('OCP\Contacts\IManager') + ->disableOriginalConstructor() + ->getMock(); + + $this->app = new Application(); + $this->container = $this->app->getContainer(); + $c = $this->container; + $this->config = $c->query(IServerContainer::class)->getConfig(); + $this->root = $c->query(IServerContainer::class)->getRootFolder(); + + $this->favoritesApiController = new FavoritesApiController( + $this->appName, + $this->request, + $c->query(IServerContainer::class), + $c->query(IServerContainer::class)->getConfig(), + $c->getServer()->getShareManager(), + $c->getServer()->getAppManager(), + $c->getServer()->getUserManager(), + $c->getServer()->getGroupManager(), + $c->query(IServerContainer::class)->getL10N($c->query('AppName')), + $c->query(IServerContainer::class)->getLogger(), + $c->query(FavoritesService::class), + 'test' + ); + + $this->favoritesApiController2 = new FavoritesApiController( + $this->appName, + $this->request, + $c->query(IServerContainer::class), + $c->query(IServerContainer::class)->getConfig(), + $c->getServer()->getShareManager(), + $c->getServer()->getAppManager(), + $c->getServer()->getUserManager(), + $c->getServer()->getGroupManager(), + $c->query(IServerContainer::class)->getL10N($c->query('AppName')), + $c->query(IServerContainer::class)->getLogger(), + $c->query(FavoritesService::class), + 'test2' + ); + + $this->utilsController = new UtilsController( + $this->appName, + $this->request, + $c->query(IServerContainer::class)->getConfig(), + $c->getServer()->getAppManager(), + $this->root, + 'test' + ); + } + + public static function tearDownAfterClass(): void { + //$app = new Application(); + //$c = $app->getContainer(); + //$user = $c->getServer()->getUserManager()->get('test'); + //$user->delete(); + //$user = $c->getServer()->getUserManager()->get('test2'); + //$user->delete(); + //$user = $c->getServer()->getUserManager()->get('test3'); + //$user->delete(); + //$c->getServer()->getGroupManager()->get('group1test')->delete(); + //$c->getServer()->getGroupManager()->get('group2test')->delete(); + } + + protected function tearDown(): void { + // in case there was a failure and something was not deleted + $resp = $this->favoritesApiController->getFavorites('1.0'); + $data = $resp->getData(); + foreach ($data as $fav) { + $resp = $this->favoritesApiController->deleteFavorite($fav['id']); + } + } + + public function testAddFavorites() { + // correct values + $resp = $this->favoritesApiController->addFavorite('1.0', 'one', 3.1, 4.2, '', null, null); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals('one', $data['name']); + $id1 = $data['id']; + + $resp = $this->favoritesApiController->addFavorite('1.0', '', 3.1, 4.2, '', null, null); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals('', $data['name']); + $id2 = $data['id']; + + // Invalid values + $resp = $this->favoritesApiController->addFavorite('1.0', 'one', 'lat', 4.2, '', null, null); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + + $resp = $this->favoritesApiController->addFavorite('1.0', 'one', 3.1, 'lon', '', null, null); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + + // get favorites + $resp = $this->favoritesApiController->getFavorites('1.0'); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals(2, count($data)); + + //// get favorites using etag + //$etag = $resp->getEtag(); + //var_dump($etag); + //$this->request->setHeader('If-None-Match', '"'.$etag.'"'); + //$resp = $this->favoritesApiController->getFavorites('1.0'); + //$status = $resp->getStatus(); + //$this->assertEquals(200, $status); + //$data = $resp->getData(); + //$this->assertEquals(2, count($data)); + + // delete created favorites + $resp = $this->favoritesApiController->deleteFavorite($id1); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals('DELETED', $data); + + $resp = $this->favoritesApiController->deleteFavorite($id2); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals('DELETED', $data); + + // delete something that does not exist + $resp = $this->favoritesApiController->deleteFavorite($id2); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + } + + public function testEditFavorites() { + // valid edition + $resp = $this->favoritesApiController->addFavorite('1.0', 'a', 3.1, 4.1, 'cat1', null, null); + $favId = $resp->getData()['id']; + + $resp = $this->favoritesApiController->editFavorite($favId, 'aa', 3.2, 4.2, 'cat2', 'comment', 'ext'); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals($favId, $data['id']); + + $resp = $this->favoritesApiController->getFavorites('1.0'); + $favs = $resp->getData(); + $seen = false; + foreach ($favs as $fav) { + if ($fav['id'] === $favId) { + $seen = true; + $this->assertEquals('aa', $fav['name']); + $this->assertEquals(3.2, $fav['lat']); + $this->assertEquals(4.2, $fav['lng']); + $this->assertEquals('cat2', $fav['category']); + $this->assertEquals('comment', $fav['comment']); + $this->assertEquals('ext', $fav['extensions']); + } + } + $this->assertEquals(true, $seen); + + // invalid edition + $resp = $this->favoritesApiController->editFavorite($favId, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('Invalid values', $data); + + $resp = $this->favoritesApiController->editFavorite(-1, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('No such favorite', $data); + } } diff --git a/tests/Unit/Controller/FavoritesControllerTest.php b/tests/Unit/Controller/FavoritesControllerTest.php index a0648f2af..73f13044c 100644 --- a/tests/Unit/Controller/FavoritesControllerTest.php +++ b/tests/Unit/Controller/FavoritesControllerTest.php @@ -13,215 +13,208 @@ namespace OCA\Maps\Controller; -use \OCA\Maps\AppInfo\Application; +use OCA\Maps\AppInfo\Application; use OCA\Maps\DB\FavoriteShareMapper; -use \OCA\Maps\Service\FavoritesService; +use OCA\Maps\Service\FavoritesService; use OCP\AppFramework\Http; -use \OCP\IServerContainer; - -class FavoritesControllerTest extends \PHPUnit\Framework\TestCase -{ - private $appName; - private $request; - private $contacts; - - private $container; - private $config; - private $app; - - private $pageController; - private $pageController2; - private $utilsController; - private $root; - - /* @var FavoritesController */ - private $favoritesController; - - /* @var FavoritesController */ - private $favoritesController2; - - public static function setUpBeforeClass(): void - { - $app = new Application(); - $c = $app->getContainer(); - - $user = $c->getServer()->getUserManager()->get('test'); - $user2 = $c->getServer()->getUserManager()->get('test2'); - $user3 = $c->getServer()->getUserManager()->get('test3'); - $group = $c->getServer()->getGroupManager()->get('group1test'); - $group2 = $c->getServer()->getGroupManager()->get('group2test'); - - // CREATE DUMMY USERS - if ($user === null) { - $u1 = $c->getServer()->getUserManager()->createUser('test', 'tatotitoTUTU'); - $u1->setEMailAddress('toto@toto.net'); - } - if ($user2 === null) { - $u2 = $c->getServer()->getUserManager()->createUser('test2', 'plopinoulala000'); - } - if ($user2 === null) { - $u3 = $c->getServer()->getUserManager()->createUser('test3', 'yeyeahPASSPASS'); - } - if ($group === null) { - $c->getServer()->getGroupManager()->createGroup('group1test'); - $u1 = $c->getServer()->getUserManager()->get('test'); - $c->getServer()->getGroupManager()->get('group1test')->addUser($u1); - } - if ($group2 === null) { - $c->getServer()->getGroupManager()->createGroup('group2test'); - $u2 = $c->getServer()->getUserManager()->get('test2'); - $c->getServer()->getGroupManager()->get('group2test')->addUser($u2); - } - } - - protected function setUp(): void - { - $this->appName = 'maps'; - $this->request = $this->getMockBuilder('\OCP\IRequest') - ->disableOriginalConstructor() - ->getMock(); - $this->contacts = $this->getMockBuilder('OCP\Contacts\IManager') - ->disableOriginalConstructor() - ->getMock(); - - $this->app = new Application(); - $this->container = $this->app->getContainer(); - $c = $this->container; - $this->config = $c->query(IServerContainer::class)->getConfig(); - $this->root = $c->query(IServerContainer::class)->getRootFolder(); - - $this->favoritesController = new FavoritesController( - $this->appName, - $this->request, - $c->query(IServerContainer::class), - $c->query(IServerContainer::class)->getConfig(), - $c->getServer()->getShareManager(), - $c->getServer()->getAppManager(), - $c->getServer()->getUserManager(), - $c->getServer()->getGroupManager(), - $c->query(IServerContainer::class)->getL10N($c->query('AppName')), - $c->query(IServerContainer::class)->getLogger(), - $c->query(FavoritesService::class), - $c->query(IServerContainer::class)->getDateTimeZone(), - $c->query(FavoriteShareMapper::class), - 'test' - ); - - $this->favoritesController2 = new FavoritesController( - $this->appName, - $this->request, - $c->query(IServerContainer::class), - $c->query(IServerContainer::class)->getConfig(), - $c->getServer()->getShareManager(), - $c->getServer()->getAppManager(), - $c->getServer()->getUserManager(), - $c->getServer()->getGroupManager(), - $c->query(IServerContainer::class)->getL10N($c->query('AppName')), - $c->query(IServerContainer::class)->getLogger(), - $c->query(FavoritesService::class), - $c->query(IServerContainer::class)->getDateTimeZone(), - $c->query(FavoriteShareMapper::class), - 'test2' - ); - - $this->utilsController = new UtilsController( - $this->appName, - $this->request, - $c->query(IServerContainer::class)->getConfig(), - $c->getServer()->getAppManager(), - $this->root, - 'test' - ); - $this->mapFolder = $this->createMapFolder(); - } - - private function createMapFolder() { - $userFolder = $this->root->getUserFolder('test'); - if ($userFolder->nodeExists('Map')) { - return $userFolder->get('Map')->delete(); +use OCP\IServerContainer; + +class FavoritesControllerTest extends \PHPUnit\Framework\TestCase { + private $appName; + private $request; + private $contacts; + + private $container; + private $config; + private $app; + + private $pageController; + private $pageController2; + private $utilsController; + private $root; + + /* @var FavoritesController */ + private $favoritesController; + + /* @var FavoritesController */ + private $favoritesController2; + + public static function setUpBeforeClass(): void { + $app = new Application(); + $c = $app->getContainer(); + + $user = $c->getServer()->getUserManager()->get('test'); + $user2 = $c->getServer()->getUserManager()->get('test2'); + $user3 = $c->getServer()->getUserManager()->get('test3'); + $group = $c->getServer()->getGroupManager()->get('group1test'); + $group2 = $c->getServer()->getGroupManager()->get('group2test'); + + // CREATE DUMMY USERS + if ($user === null) { + $u1 = $c->getServer()->getUserManager()->createUser('test', 'tatotitoTUTU'); + $u1->setEMailAddress('toto@toto.net'); + } + if ($user2 === null) { + $u2 = $c->getServer()->getUserManager()->createUser('test2', 'plopinoulala000'); + } + if ($user2 === null) { + $u3 = $c->getServer()->getUserManager()->createUser('test3', 'yeyeahPASSPASS'); + } + if ($group === null) { + $c->getServer()->getGroupManager()->createGroup('group1test'); + $u1 = $c->getServer()->getUserManager()->get('test'); + $c->getServer()->getGroupManager()->get('group1test')->addUser($u1); + } + if ($group2 === null) { + $c->getServer()->getGroupManager()->createGroup('group2test'); + $u2 = $c->getServer()->getUserManager()->get('test2'); + $c->getServer()->getGroupManager()->get('group2test')->addUser($u2); + } } - return $userFolder->newFolder('Map'); - } - - public static function tearDownAfterClass(): void - { - //$app = new Application(); - //$c = $app->getContainer(); - //$user = $c->getServer()->getUserManager()->get('test'); - //$user->delete(); - //$user = $c->getServer()->getUserManager()->get('test2'); - //$user->delete(); - //$user = $c->getServer()->getUserManager()->get('test3'); - //$user->delete(); - //$c->getServer()->getGroupManager()->get('group1test')->delete(); - //$c->getServer()->getGroupManager()->get('group2test')->delete(); - } - - protected function tearDown(): void - { - // in case there was a failure and something was not deleted - $resp = $this->favoritesController->getFavorites(); - $data = $resp->getData(); - foreach ($data as $fav) { - $resp = $this->favoritesController->deleteFavorite($fav['id']); - } - } - - public function testAddFavorites() - { - // correct values - $resp = $this->favoritesController->addFavorite('one', 3.1, 4.2, '', null, null); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals('one', $data['name']); - $id1 = $data['id']; - - $resp = $this->favoritesController->addFavorite('', 3.1, 4.2, '', null, null); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals('', $data['name']); - $id2 = $data['id']; - - // invalid values -/* ToDo: Probably test for type error - $resp = $this->favoritesController->addFavorite('one', 'lat', 4.2, '', null, null); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - - $resp = $this->favoritesController->addFavorite('one', 3.1, 'lon', '', null, null); - $status = $resp->getStatus(); - $this->assertEquals(400, $status);*/ - - // get favorites - $resp = $this->favoritesController->getFavorites(); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals(2, count($data)); - - // delete created favorites - $resp = $this->favoritesController->deleteFavorite($id1); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals('DELETED', $data); - - $resp = $this->favoritesController->deleteFavorite($id2); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals('DELETED', $data); - - // delete something that does not exist - $resp = $this->favoritesController->deleteFavorite($id2); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - } - - public function testAddFavoritesMyMap() - { + + protected function setUp(): void { + $this->appName = 'maps'; + $this->request = $this->getMockBuilder('\OCP\IRequest') + ->disableOriginalConstructor() + ->getMock(); + $this->contacts = $this->getMockBuilder('OCP\Contacts\IManager') + ->disableOriginalConstructor() + ->getMock(); + + $this->app = new Application(); + $this->container = $this->app->getContainer(); + $c = $this->container; + $this->config = $c->query(IServerContainer::class)->getConfig(); + $this->root = $c->query(IServerContainer::class)->getRootFolder(); + + $this->favoritesController = new FavoritesController( + $this->appName, + $this->request, + $c->query(IServerContainer::class), + $c->query(IServerContainer::class)->getConfig(), + $c->getServer()->getShareManager(), + $c->getServer()->getAppManager(), + $c->getServer()->getUserManager(), + $c->getServer()->getGroupManager(), + $c->query(IServerContainer::class)->getL10N($c->query('AppName')), + $c->query(IServerContainer::class)->getLogger(), + $c->query(FavoritesService::class), + $c->query(IServerContainer::class)->getDateTimeZone(), + $c->query(FavoriteShareMapper::class), + 'test' + ); + + $this->favoritesController2 = new FavoritesController( + $this->appName, + $this->request, + $c->query(IServerContainer::class), + $c->query(IServerContainer::class)->getConfig(), + $c->getServer()->getShareManager(), + $c->getServer()->getAppManager(), + $c->getServer()->getUserManager(), + $c->getServer()->getGroupManager(), + $c->query(IServerContainer::class)->getL10N($c->query('AppName')), + $c->query(IServerContainer::class)->getLogger(), + $c->query(FavoritesService::class), + $c->query(IServerContainer::class)->getDateTimeZone(), + $c->query(FavoriteShareMapper::class), + 'test2' + ); + + $this->utilsController = new UtilsController( + $this->appName, + $this->request, + $c->query(IServerContainer::class)->getConfig(), + $c->getServer()->getAppManager(), + $this->root, + 'test' + ); + $this->mapFolder = $this->createMapFolder(); + } + + private function createMapFolder() { + $userFolder = $this->root->getUserFolder('test'); + if ($userFolder->nodeExists('Map')) { + return $userFolder->get('Map')->delete(); + } + return $userFolder->newFolder('Map'); + } + + public static function tearDownAfterClass(): void { + //$app = new Application(); + //$c = $app->getContainer(); + //$user = $c->getServer()->getUserManager()->get('test'); + //$user->delete(); + //$user = $c->getServer()->getUserManager()->get('test2'); + //$user->delete(); + //$user = $c->getServer()->getUserManager()->get('test3'); + //$user->delete(); + //$c->getServer()->getGroupManager()->get('group1test')->delete(); + //$c->getServer()->getGroupManager()->get('group2test')->delete(); + } + + protected function tearDown(): void { + // in case there was a failure and something was not deleted + $resp = $this->favoritesController->getFavorites(); + $data = $resp->getData(); + foreach ($data as $fav) { + $resp = $this->favoritesController->deleteFavorite($fav['id']); + } + } + + public function testAddFavorites() { + // correct values + $resp = $this->favoritesController->addFavorite('one', 3.1, 4.2, '', null, null); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals('one', $data['name']); + $id1 = $data['id']; + + $resp = $this->favoritesController->addFavorite('', 3.1, 4.2, '', null, null); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals('', $data['name']); + $id2 = $data['id']; + + // invalid values + /* ToDo: Probably test for type error + $resp = $this->favoritesController->addFavorite('one', 'lat', 4.2, '', null, null); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + + $resp = $this->favoritesController->addFavorite('one', 3.1, 'lon', '', null, null); + $status = $resp->getStatus(); + $this->assertEquals(400, $status);*/ + + // get favorites + $resp = $this->favoritesController->getFavorites(); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals(2, count($data)); + + // delete created favorites + $resp = $this->favoritesController->deleteFavorite($id1); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals('DELETED', $data); + + $resp = $this->favoritesController->deleteFavorite($id2); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals('DELETED', $data); + + // delete something that does not exist + $resp = $this->favoritesController->deleteFavorite($id2); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + } + + public function testAddFavoritesMyMap() { $myMapId = $this->mapFolder->getId(); // correct values $resp = $this->favoritesController->addFavorite('one', 3.1, 4.2, '', null, null, $myMapId); @@ -281,169 +274,166 @@ public function testAddFavoritesMyMap() $this->assertEquals(400, $status); } - public function testImportExportFavorites() - { - $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); - $content1 = file_get_contents('tests/test_files/favoritesOk.gpx'); - $newFile = $userfolder->newFile('favoritesOk.gpx'); - $newFile->putContent($content1); - - $resp = $this->favoritesController->importFavorites('/favoritesOk.gpx'); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals(27, $data['nbImported']); - - // get favorites - $resp = $this->favoritesController->getFavorites(); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals(27, count($data)); - $nbFavorites = count($data); - $categoryCount = []; - foreach ($data as $fav) { - $categoryCount[$fav['category']] = isset($categoryCount[$fav['category']]) ? ($categoryCount[$fav['category']] + 1) : 1; - } - $categories = array_keys($categoryCount); - - // import errors - $userfolder->newFile('dummy.pdf')->putContent('dummy content'); - - $resp = $this->favoritesController->importFavorites('/dummy.gpx'); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('File does not exist', $data); - - $resp = $this->favoritesController->importFavorites('/dummy.pdf'); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('Invalid file extension', $data); - - // export and compare - $resp = $this->favoritesController->exportFavorites($categories, null, null, true); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $exportPath = $resp->getData(); - $this->assertEquals(true, $userfolder->nodeExists($exportPath)); - - // parse xml and compare number of favorite for each category - $xmLData = $userfolder->get($exportPath)->getContent(); - $xml = simplexml_load_string($xmLData); - $wpts = $xml->wpt; - $this->assertEquals($nbFavorites, count($wpts)); - $categoryCountExport = []; - foreach ($wpts as $wpt) { - $cat = (string)$wpt->type[0]; - $categoryCountExport[$cat] = isset($categoryCountExport[$cat]) ? ($categoryCountExport[$cat] + 1) : 1; - } - foreach ($categoryCount as $cat => $nb) { - $this->assertEquals($categoryCountExport[$cat], $nb); - } - - // export error - $resp = $this->favoritesController->exportFavorites(null, null, null, true); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('Nothing to export', $data); - - $userfolder->get('/Maps')->delete(); - $userfolder->newFile('Maps')->putContent('dummy content'); - $resp = $this->favoritesController->exportFavorites($categories, null, null, true); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('/Maps is not a directory', $data); - $userfolder->get('/Maps')->delete(); - - // delete all favorites - $resp = $this->favoritesController->getFavorites(); - $data = $resp->getData(); - $favIds = []; - foreach ($data as $fav) { - array_push($favIds, $fav['id']); - } - $resp = $this->favoritesController->deleteFavorites($favIds); - - // and then try to export - $resp = $this->favoritesController->exportFavorites($categories, null, null, true); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('Nothing to export', $data); - } - - - - public function testEditFavorites() - { - // valid edition - $resp = $this->favoritesController->addFavorite('a', 3.1, 4.1, 'cat1', null, null); - $favId = $resp->getData()['id']; - - $resp = $this->favoritesController->editFavorite($favId, 'aa', 3.2, 4.2, 'cat2', 'comment', 'ext'); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals($favId, $data['id']); - - $resp = $this->favoritesController->getFavorites(); - $favs = $resp->getData(); - $seen = false; - foreach ($favs as $fav) { - if ($fav['id'] === $favId) { - $seen = true; - $this->assertEquals('aa', $fav['name']); - $this->assertEquals(3.2, $fav['lat']); - $this->assertEquals(4.2, $fav['lng']); - $this->assertEquals('cat2', $fav['category']); - $this->assertEquals('comment', $fav['comment']); - $this->assertEquals('ext', $fav['extensions']); - } - } - $this->assertEquals(true, $seen); - - // invalid edition -//ToDo: Probably test for type errors -// -// $resp = $this->favoritesController->editFavorite($favId, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); -// $status = $resp->getStatus(); -// $this->assertEquals(400, $status); -// $data = $resp->getData(); -// $this->assertEquals('Invalid values', $data); -// -// $resp = $this->favoritesController->editFavorite(-1, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); -// $this->assertEquals(400, $status); -// $data = $resp->getData(); -// $this->assertEquals('No such favorite', $data); - - // rename category - $resp = $this->favoritesController->addFavorite('b', 3.1, 4.2, 'cat1', null, null); - $resp = $this->favoritesController->addFavorite('one', 3.1, 4.2, 'cat2', null, null); - - $resp = $this->favoritesController->renameCategories(['cat1'], 'cat1RENAMED'); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals('RENAMED', $data); - // check if renaming worked - $resp = $this->favoritesController->getFavorites(); - $favs = $resp->getData(); - $seen = false; - foreach ($favs as $fav) { - if ($fav['name'] === 'b') { - $seen = true; - $this->assertEquals('cat1RENAMED', $fav['category']); - } - } - $this->assertEquals(true, $seen); - } - - public function testEditFavoritesMyMap() - { + public function testImportExportFavorites() { + $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); + $content1 = file_get_contents('tests/test_files/favoritesOk.gpx'); + $newFile = $userfolder->newFile('favoritesOk.gpx'); + $newFile->putContent($content1); + + $resp = $this->favoritesController->importFavorites('/favoritesOk.gpx'); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals(27, $data['nbImported']); + + // get favorites + $resp = $this->favoritesController->getFavorites(); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals(27, count($data)); + $nbFavorites = count($data); + $categoryCount = []; + foreach ($data as $fav) { + $categoryCount[$fav['category']] = isset($categoryCount[$fav['category']]) ? ($categoryCount[$fav['category']] + 1) : 1; + } + $categories = array_keys($categoryCount); + + // import errors + $userfolder->newFile('dummy.pdf')->putContent('dummy content'); + + $resp = $this->favoritesController->importFavorites('/dummy.gpx'); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('File does not exist', $data); + + $resp = $this->favoritesController->importFavorites('/dummy.pdf'); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('Invalid file extension', $data); + + // export and compare + $resp = $this->favoritesController->exportFavorites($categories, null, null, true); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $exportPath = $resp->getData(); + $this->assertEquals(true, $userfolder->nodeExists($exportPath)); + + // parse xml and compare number of favorite for each category + $xmLData = $userfolder->get($exportPath)->getContent(); + $xml = simplexml_load_string($xmLData); + $wpts = $xml->wpt; + $this->assertEquals($nbFavorites, count($wpts)); + $categoryCountExport = []; + foreach ($wpts as $wpt) { + $cat = (string)$wpt->type[0]; + $categoryCountExport[$cat] = isset($categoryCountExport[$cat]) ? ($categoryCountExport[$cat] + 1) : 1; + } + foreach ($categoryCount as $cat => $nb) { + $this->assertEquals($categoryCountExport[$cat], $nb); + } + + // export error + $resp = $this->favoritesController->exportFavorites(null, null, null, true); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('Nothing to export', $data); + + $userfolder->get('/Maps')->delete(); + $userfolder->newFile('Maps')->putContent('dummy content'); + $resp = $this->favoritesController->exportFavorites($categories, null, null, true); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('/Maps is not a directory', $data); + $userfolder->get('/Maps')->delete(); + + // delete all favorites + $resp = $this->favoritesController->getFavorites(); + $data = $resp->getData(); + $favIds = []; + foreach ($data as $fav) { + array_push($favIds, $fav['id']); + } + $resp = $this->favoritesController->deleteFavorites($favIds); + + // and then try to export + $resp = $this->favoritesController->exportFavorites($categories, null, null, true); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('Nothing to export', $data); + } + + + + public function testEditFavorites() { + // valid edition + $resp = $this->favoritesController->addFavorite('a', 3.1, 4.1, 'cat1', null, null); + $favId = $resp->getData()['id']; + + $resp = $this->favoritesController->editFavorite($favId, 'aa', 3.2, 4.2, 'cat2', 'comment', 'ext'); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals($favId, $data['id']); + + $resp = $this->favoritesController->getFavorites(); + $favs = $resp->getData(); + $seen = false; + foreach ($favs as $fav) { + if ($fav['id'] === $favId) { + $seen = true; + $this->assertEquals('aa', $fav['name']); + $this->assertEquals(3.2, $fav['lat']); + $this->assertEquals(4.2, $fav['lng']); + $this->assertEquals('cat2', $fav['category']); + $this->assertEquals('comment', $fav['comment']); + $this->assertEquals('ext', $fav['extensions']); + } + } + $this->assertEquals(true, $seen); + + // invalid edition + //ToDo: Probably test for type errors + // + // $resp = $this->favoritesController->editFavorite($favId, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); + // $status = $resp->getStatus(); + // $this->assertEquals(400, $status); + // $data = $resp->getData(); + // $this->assertEquals('Invalid values', $data); + // + // $resp = $this->favoritesController->editFavorite(-1, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext'); + // $this->assertEquals(400, $status); + // $data = $resp->getData(); + // $this->assertEquals('No such favorite', $data); + + // rename category + $resp = $this->favoritesController->addFavorite('b', 3.1, 4.2, 'cat1', null, null); + $resp = $this->favoritesController->addFavorite('one', 3.1, 4.2, 'cat2', null, null); + + $resp = $this->favoritesController->renameCategories(['cat1'], 'cat1RENAMED'); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals('RENAMED', $data); + // check if renaming worked + $resp = $this->favoritesController->getFavorites(); + $favs = $resp->getData(); + $seen = false; + foreach ($favs as $fav) { + if ($fav['name'] === 'b') { + $seen = true; + $this->assertEquals('cat1RENAMED', $fav['category']); + } + } + $this->assertEquals(true, $seen); + } + + public function testEditFavoritesMyMap() { $this->mapFolder = $this->createMapFolder(); $myMapId = $this->mapFolder->getId(); // valid edition @@ -473,16 +463,16 @@ public function testEditFavoritesMyMap() // invalid edition //todo: check for type error -// $resp = $this->favoritesController->editFavorite($favId, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext', $myMapId); -// $status = $resp->getStatus(); -// $this->assertEquals(400, $status); -// $data = $resp->getData(); -// $this->assertEquals('invalid values', $data); -// -// $resp = $this->favoritesController->editFavorite(-1, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext', $myMapId); -// $this->assertEquals(400, $status); -// $data = $resp->getData(); -// $this->assertEquals('no such favorite', $data); + // $resp = $this->favoritesController->editFavorite($favId, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext', $myMapId); + // $status = $resp->getStatus(); + // $this->assertEquals(400, $status); + // $data = $resp->getData(); + // $this->assertEquals('invalid values', $data); + // + // $resp = $this->favoritesController->editFavorite(-1, 'aa', 'invalid lat', 4.2, 'cat2', 'comment', 'ext', $myMapId); + // $this->assertEquals(400, $status); + // $data = $resp->getData(); + // $this->assertEquals('no such favorite', $data); // rename category $resp = $this->favoritesController->addFavorite('b', 3.1, 4.2, 'cat1', null, null, $myMapId); @@ -506,110 +496,110 @@ public function testEditFavoritesMyMap() $this->assertEquals(true, $seen); } - public function testShareUnShareCategory() { - $categoryName = 'test3458565'; - - $id = $this->favoritesController - ->addFavorite('Test', 0, 0, $categoryName, "", null) - ->getData()['id']; + public function testShareUnShareCategory() { + $categoryName = 'test3458565'; - $response1 = $this->favoritesController->shareCategory($categoryName); - $response2 = $this->favoritesController->unShareCategory($categoryName); + $id = $this->favoritesController + ->addFavorite('Test', 0, 0, $categoryName, '', null) + ->getData()['id']; - $this->favoritesController->deleteFavorite($id); + $response1 = $this->favoritesController->shareCategory($categoryName); + $response2 = $this->favoritesController->unShareCategory($categoryName); - $this->assertEquals(Http::STATUS_OK, $response1->getStatus()); - $this->assertEquals(Http::STATUS_OK, $response2->getStatus()); + $this->favoritesController->deleteFavorite($id); - $this->assertIsString($response1->getData()->getToken()); - $this->assertTrue($response2->getData()['did_exist']); - } + $this->assertEquals(Http::STATUS_OK, $response1->getStatus()); + $this->assertEquals(Http::STATUS_OK, $response2->getStatus()); - public function testShareUnShareCategoryNotAuthorized() { - $categoryName = 'test3458565'; + $this->assertIsString($response1->getData()->getToken()); + $this->assertTrue($response2->getData()['did_exist']); + } - $id = $this->favoritesController2 - ->addFavorite("Test2", 0, 0, $categoryName, "", null) - ->getData()['id']; + public function testShareUnShareCategoryNotAuthorized() { + $categoryName = 'test3458565'; - $response1 = $this->favoritesController->shareCategory($categoryName); - $response2 = $this->favoritesController->unShareCategory($categoryName); + $id = $this->favoritesController2 + ->addFavorite('Test2', 0, 0, $categoryName, '', null) + ->getData()['id']; - $this->favoritesController->deleteFavorite($id); + $response1 = $this->favoritesController->shareCategory($categoryName); + $response2 = $this->favoritesController->unShareCategory($categoryName); - $this->assertEquals(Http::STATUS_BAD_REQUEST, $response1->getStatus()); - $this->assertEquals(Http::STATUS_BAD_REQUEST, $response2->getStatus()); - } + $this->favoritesController->deleteFavorite($id); - public function testShareUnShareNonExistentCategory() { - $categoryName = 'non_existent'; + $this->assertEquals(Http::STATUS_BAD_REQUEST, $response1->getStatus()); + $this->assertEquals(Http::STATUS_BAD_REQUEST, $response2->getStatus()); + } - $response1 = $this->favoritesController->shareCategory($categoryName); - $response2 = $this->favoritesController->unShareCategory($categoryName); + public function testShareUnShareNonExistentCategory() { + $categoryName = 'non_existent'; - $this->favoritesController->unShareCategory($categoryName); + $response1 = $this->favoritesController->shareCategory($categoryName); + $response2 = $this->favoritesController->unShareCategory($categoryName); - $this->assertEquals(Http::STATUS_BAD_REQUEST, $response1->getStatus()); - $this->assertEquals(Http::STATUS_BAD_REQUEST, $response2->getStatus()); - } + $this->favoritesController->unShareCategory($categoryName); - public function testGetSharedCategories() { - $categoryNames = ['test345456', 'test2345465', 'test65765']; - $ids = []; + $this->assertEquals(Http::STATUS_BAD_REQUEST, $response1->getStatus()); + $this->assertEquals(Http::STATUS_BAD_REQUEST, $response2->getStatus()); + } - foreach ($categoryNames as $categoryName) { - array_push( - $ids, - $this->favoritesController - ->addFavorite("Test", 0, 0, $categoryName, "", null) - ->getData()['id'] - ); - $this->favoritesController->shareCategory($categoryName); - } + public function testGetSharedCategories() { + $categoryNames = ['test345456', 'test2345465', 'test65765']; + $ids = []; + + foreach ($categoryNames as $categoryName) { + array_push( + $ids, + $this->favoritesController + ->addFavorite('Test', 0, 0, $categoryName, '', null) + ->getData()['id'] + ); + $this->favoritesController->shareCategory($categoryName); + } - $categories = $this->favoritesController->getSharedCategories(); + $categories = $this->favoritesController->getSharedCategories(); - $this->assertIsArray($categories->getData()); + $this->assertIsArray($categories->getData()); - $mappedCategories = array_map(function ($el) { - return $el->getCategory(); - }, $categories->getData()); + $mappedCategories = array_map(function ($el) { + return $el->getCategory(); + }, $categories->getData()); - foreach ($categoryNames as $categoryName) { - $this->assertContains($categoryName, $mappedCategories); - } + foreach ($categoryNames as $categoryName) { + $this->assertContains($categoryName, $mappedCategories); + } - foreach ($categoryNames as $categoryName) { - $this->favoritesController->unShareCategory($categoryName); - } + foreach ($categoryNames as $categoryName) { + $this->favoritesController->unShareCategory($categoryName); + } - foreach ($ids as $id) { - $this->favoritesController->deleteFavorite($id); - } - } + foreach ($ids as $id) { + $this->favoritesController->deleteFavorite($id); + } + } - public function testFavoriteShareIsRenamedCorrectly() { - $categoryName = 'test03059035'; - $newCategoryName = 'test097876'; + public function testFavoriteShareIsRenamedCorrectly() { + $categoryName = 'test03059035'; + $newCategoryName = 'test097876'; - $id = $this->favoritesController - ->addFavorite("Test", 0, 0, $categoryName, "", null) - ->getData()['id']; + $id = $this->favoritesController + ->addFavorite('Test', 0, 0, $categoryName, '', null) + ->getData()['id']; - $this->favoritesController->shareCategory($categoryName); + $this->favoritesController->shareCategory($categoryName); - $this->favoritesController->renameCategories([$categoryName], $newCategoryName); + $this->favoritesController->renameCategories([$categoryName], $newCategoryName); - $shares = $this->favoritesController->getSharedCategories()->getData(); + $shares = $this->favoritesController->getSharedCategories()->getData(); - $shareNames = array_map(function($el) { - return $el->getCategory(); - }, $shares); + $shareNames = array_map(function ($el) { + return $el->getCategory(); + }, $shares); - $this->favoritesController->deleteFavorite($id); - $this->favoritesController->unShareCategory($newCategoryName); + $this->favoritesController->deleteFavorite($id); + $this->favoritesController->unShareCategory($newCategoryName); - $this->assertContains($newCategoryName, $shareNames); - $this->assertNotContains($categoryName, $shareNames); - } + $this->assertContains($newCategoryName, $shareNames); + $this->assertNotContains($categoryName, $shareNames); + } } diff --git a/tests/Unit/Controller/PageControllerTest.php b/tests/Unit/Controller/PageControllerTest.php index a3a550ec1..bc44384c7 100644 --- a/tests/Unit/Controller/PageControllerTest.php +++ b/tests/Unit/Controller/PageControllerTest.php @@ -11,53 +11,52 @@ namespace OCA\Maps\Controller; -use \OCA\Maps\AppInfo\Application; -use \OCP\AppFramework\Http\TemplateResponse; -use \OCP\EventDispatcher\IEventDispatcher; -use \OCP\IServerContainer; - +use OCA\Maps\AppInfo\Application; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\IServerContainer; class PageControllerTest extends \PHPUnit\Framework\TestCase { - private $controller; - private $userId = 'john'; - private $config; + private $controller; + private $userId = 'john'; + private $config; private $eventDispatcher; - private $app; - private $container; - - protected function setUp(): void { - $request = $this->getMockBuilder('OCP\IRequest')->getMock(); - $initialStateService = $this->getMockBuilder('OCP\IInitialStateService')->getMock(); - $this->app = new Application(); - $this->container = $this->app->getContainer(); - $c = $this->container; - $this->config = $c->query(IServerContainer::class)->getConfig(); + private $app; + private $container; + + protected function setUp(): void { + $request = $this->getMockBuilder('OCP\IRequest')->getMock(); + $initialStateService = $this->getMockBuilder('OCP\IInitialStateService')->getMock(); + $this->app = new Application(); + $this->container = $this->app->getContainer(); + $c = $this->container; + $this->config = $c->query(IServerContainer::class)->getConfig(); $this->eventDispatcher = $c->query(IServerContainer::class)->query(IEventDispatcher::class); - $this->oldGHValue = $this->config->getAppValue('maps', 'graphhopperURL'); - $this->config->setAppValue('maps', 'graphhopperURL', 'https://graphhopper.com:8080'); + $this->oldGHValue = $this->config->getAppValue('maps', 'graphhopperURL'); + $this->config->setAppValue('maps', 'graphhopperURL', 'https://graphhopper.com:8080'); - $this->controller = new PageController( - 'maps', $request, $this->eventDispatcher, $this->config, $initialStateService, $this->userId - ); - } + $this->controller = new PageController( + 'maps', $request, $this->eventDispatcher, $this->config, $initialStateService, $this->userId + ); + } - protected function tearDown(): void { - $this->config->setAppValue('maps', 'graphhopperURL', $this->oldGHValue); - } + protected function tearDown(): void { + $this->config->setAppValue('maps', 'graphhopperURL', $this->oldGHValue); + } - public function testIndex() { - $result = $this->controller->index(); + public function testIndex() { + $result = $this->controller->index(); - $this->assertEquals('main', $result->getTemplateName()); - $this->assertTrue($result instanceof TemplateResponse); - } + $this->assertEquals('main', $result->getTemplateName()); + $this->assertTrue($result instanceof TemplateResponse); + } - public function testOpenGeoLink() { - $result = $this->controller->openGeoLink('geo:1.1,2.2'); + public function testOpenGeoLink() { + $result = $this->controller->openGeoLink('geo:1.1,2.2'); - $this->assertEquals('main', $result->getTemplateName()); - $this->assertTrue($result instanceof TemplateResponse); - } + $this->assertEquals('main', $result->getTemplateName()); + $this->assertTrue($result instanceof TemplateResponse); + } } diff --git a/tests/Unit/Controller/PhotosControllerTest.php b/tests/Unit/Controller/PhotosControllerTest.php index a3ee4aac6..1e46d9514 100644 --- a/tests/Unit/Controller/PhotosControllerTest.php +++ b/tests/Unit/Controller/PhotosControllerTest.php @@ -11,207 +11,203 @@ namespace OCA\Maps\Controller; -use \OCA\Maps\AppInfo\Application; -use OCP\DB\QueryBuilder\IQueryBuilder; +use OCA\Maps\AppInfo\Application; +use OCA\Maps\DB\GeophotoMapper; use OCA\Maps\Service\GeophotoService; use OCA\Maps\Service\PhotofilesService; -use OCA\Maps\Service\TracksService; -use OCA\Maps\Service\DevicesService; -use OCA\Maps\DB\GeophotoMapper; -use OCP\AppFramework\Http\TemplateResponse; -use \OCP\IServerContainer; - +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IServerContainer; class PhotosControllerTest extends \PHPUnit\Framework\TestCase { - private $appName; - private $request; - private $contacts; + private $appName; + private $request; + private $contacts; - private $container; - private $config; - private $app; + private $container; + private $config; + private $app; - private $photosController; - private $photosController2; - private $utilsController; + private $photosController; + private $photosController2; + private $utilsController; - private $photoFileService; + private $photoFileService; private $GeoPhotosService; - public static function setUpBeforeClass(): void { - $app = new Application(); - $c = $app->getContainer(); - - $user = $c->getServer()->getUserManager()->get('test'); - $user2 = $c->getServer()->getUserManager()->get('test2'); - $user3 = $c->getServer()->getUserManager()->get('test3'); - $group = $c->getServer()->getGroupManager()->get('group1test'); - $group2 = $c->getServer()->getGroupManager()->get('group2test'); - - // CREATE DUMMY USERS - if ($user === null) { - $u1 = $c->getServer()->getUserManager()->createUser('test', 'tatotitoTUTU'); - $u1->setEMailAddress('toto@toto.net'); - } - if ($user2 === null) { - $u2 = $c->getServer()->getUserManager()->createUser('test2', 'plopinoulala000'); - } - if ($user2 === null) { - $u3 = $c->getServer()->getUserManager()->createUser('test3', 'yeyeahPASSPASS'); - } - if ($group === null) { - $c->getServer()->getGroupManager()->createGroup('group1test'); - $u1 = $c->getServer()->getUserManager()->get('test'); - $c->getServer()->getGroupManager()->get('group1test')->addUser($u1); - } - if ($group2 === null) { - $c->getServer()->getGroupManager()->createGroup('group2test'); - $u2 = $c->getServer()->getUserManager()->get('test2'); - $c->getServer()->getGroupManager()->get('group2test')->addUser($u2); - } - } - - protected function setUp(): void { - $this->appName = 'maps'; - $this->request = $this->getMockBuilder('\OCP\IRequest') - ->disableOriginalConstructor() - ->getMock(); - $this->contacts = $this->getMockBuilder('OCP\Contacts\IManager') - ->disableOriginalConstructor() - ->getMock(); - - $this->app = new Application(); - $this->container = $this->app->getContainer(); - $c = $this->container; - $this->config = $c->query(IServerContainer::class)->getConfig(); - - $this->rootFolder = $c->query(IServerContainer::class)->getRootFolder(); + public static function setUpBeforeClass(): void { + $app = new Application(); + $c = $app->getContainer(); + + $user = $c->getServer()->getUserManager()->get('test'); + $user2 = $c->getServer()->getUserManager()->get('test2'); + $user3 = $c->getServer()->getUserManager()->get('test3'); + $group = $c->getServer()->getGroupManager()->get('group1test'); + $group2 = $c->getServer()->getGroupManager()->get('group2test'); + + // CREATE DUMMY USERS + if ($user === null) { + $u1 = $c->getServer()->getUserManager()->createUser('test', 'tatotitoTUTU'); + $u1->setEMailAddress('toto@toto.net'); + } + if ($user2 === null) { + $u2 = $c->getServer()->getUserManager()->createUser('test2', 'plopinoulala000'); + } + if ($user2 === null) { + $u3 = $c->getServer()->getUserManager()->createUser('test3', 'yeyeahPASSPASS'); + } + if ($group === null) { + $c->getServer()->getGroupManager()->createGroup('group1test'); + $u1 = $c->getServer()->getUserManager()->get('test'); + $c->getServer()->getGroupManager()->get('group1test')->addUser($u1); + } + if ($group2 === null) { + $c->getServer()->getGroupManager()->createGroup('group2test'); + $u2 = $c->getServer()->getUserManager()->get('test2'); + $c->getServer()->getGroupManager()->get('group2test')->addUser($u2); + } + } + + protected function setUp(): void { + $this->appName = 'maps'; + $this->request = $this->getMockBuilder('\OCP\IRequest') + ->disableOriginalConstructor() + ->getMock(); + $this->contacts = $this->getMockBuilder('OCP\Contacts\IManager') + ->disableOriginalConstructor() + ->getMock(); + + $this->app = new Application(); + $this->container = $this->app->getContainer(); + $c = $this->container; + $this->config = $c->query(IServerContainer::class)->getConfig(); + + $this->rootFolder = $c->query(IServerContainer::class)->getRootFolder(); $this->GeoPhotosService = $c->query(GeoPhotoService::class); - $this->photoFileService = new PhotoFilesService( - $c->query(IServerContainer::class)->getLogger(), + $this->photoFileService = new PhotoFilesService( + $c->query(IServerContainer::class)->getLogger(), $c->query(IServerContainer::class)->getMemCacheFactory(), - $this->rootFolder, - $c->query(IServerContainer::class)->getL10N($c->query('AppName')), - $c->query(GeophotoMapper::class), - $c->query(IServerContainer::class)->getShareManager(), - $c->query(\OCP\BackgroundJob\IJobList::class) - ); - - $this->photosController = new PhotosController( - $this->appName, - $c->query(IServerContainer::class)->getLogger(), - $this->request, - $this->GeoPhotosService, - $this->photoFileService, + $this->rootFolder, + $c->query(IServerContainer::class)->getL10N($c->query('AppName')), + $c->query(GeophotoMapper::class), + $c->query(IServerContainer::class)->getShareManager(), + $c->query(\OCP\BackgroundJob\IJobList::class) + ); + + $this->photosController = new PhotosController( + $this->appName, + $c->query(IServerContainer::class)->getLogger(), + $this->request, + $this->GeoPhotosService, + $this->photoFileService, $this->rootFolder, 'test' - ); - - $this->photosController2 = new PhotosController( - $this->appName, - $c->query(IServerContainer::class)->getLogger(), - $this->request, - $c->query(GeoPhotoService::class), - $this->photoFileService, + ); + + $this->photosController2 = new PhotosController( + $this->appName, + $c->query(IServerContainer::class)->getLogger(), + $this->request, + $c->query(GeoPhotoService::class), + $this->photoFileService, $this->rootFolder, - 'test2' - ); - - $this->utilsController = new UtilsController( - $this->appName, - $this->request, - $c->query(IServerContainer::class)->getConfig(), - $c->getServer()->getAppManager(), + 'test2' + ); + + $this->utilsController = new UtilsController( + $this->appName, + $this->request, + $c->query(IServerContainer::class)->getConfig(), + $c->getServer()->getAppManager(), $this->rootFolder, - 'test' - ); - - $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); - // delete files - if ($userfolder->nodeExists('nc.jpg')) { - $file = $userfolder->get('nc.jpg'); - $file->delete(); - } - if ($userfolder->nodeExists('nut.jpg')) { - $file = $userfolder->get('nut.jpg'); - $file->delete(); - } - // delete db - $qb = $c->query(IServerContainer::class)->query(\OCP\IDBConnection::class)->getQueryBuilder(); - $qb->delete('maps_photos') - ->where( - $qb->expr()->eq('user_id', $qb->createNamedParameter('test', IQueryBuilder::PARAM_STR)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - - public static function tearDownAfterClass(): void { - //$app = new Application(); - //$c = $app->getContainer(); - //$user = $c->getServer()->getUserManager()->get('test'); - //$user->delete(); - //$user = $c->getServer()->getUserManager()->get('test2'); - //$user->delete(); - //$user = $c->getServer()->getUserManager()->get('test3'); - //$user->delete(); - //$c->getServer()->getGroupManager()->get('group1test')->delete(); - //$c->getServer()->getGroupManager()->get('group2test')->delete(); - } - - protected function tearDown(): void { - // in case there was a failure and something was not deleted - } - - public function testAddGetPhotos() { - $c = $this->app->getContainer(); - - $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); - - $filename = 'tests/test_files/nc.jpg'; - $handle = fopen($filename, 'rb'); - $content1 = fread($handle, filesize($filename)); - fclose($handle); - $file = $userfolder->newFile('nc.jpgg'); - $fp = $file->fopen('wb'); - fwrite($fp, $content1); - fclose($fp); - $file->touch(); - // rename - $file = $userfolder->get('nc.jpgg'); - $file->move($userfolder->getPath().'/nc.jpg'); - $file = $userfolder->get('nc.jpg'); - $file->touch(); + 'test' + ); + + $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); + // delete files + if ($userfolder->nodeExists('nc.jpg')) { + $file = $userfolder->get('nc.jpg'); + $file->delete(); + } + if ($userfolder->nodeExists('nut.jpg')) { + $file = $userfolder->get('nut.jpg'); + $file->delete(); + } + // delete db + $qb = $c->query(IServerContainer::class)->query(\OCP\IDBConnection::class)->getQueryBuilder(); + $qb->delete('maps_photos') + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter('test', IQueryBuilder::PARAM_STR)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + + public static function tearDownAfterClass(): void { + //$app = new Application(); + //$c = $app->getContainer(); + //$user = $c->getServer()->getUserManager()->get('test'); + //$user->delete(); + //$user = $c->getServer()->getUserManager()->get('test2'); + //$user->delete(); + //$user = $c->getServer()->getUserManager()->get('test3'); + //$user->delete(); + //$c->getServer()->getGroupManager()->get('group1test')->delete(); + //$c->getServer()->getGroupManager()->get('group2test')->delete(); + } + + protected function tearDown(): void { + // in case there was a failure and something was not deleted + } + + public function testAddGetPhotos() { + $c = $this->app->getContainer(); + + $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); + + $filename = 'tests/test_files/nc.jpg'; + $handle = fopen($filename, 'rb'); + $content1 = fread($handle, filesize($filename)); + fclose($handle); + $file = $userfolder->newFile('nc.jpgg'); + $fp = $file->fopen('wb'); + fwrite($fp, $content1); + fclose($fp); + $file->touch(); + // rename + $file = $userfolder->get('nc.jpgg'); + $file->move($userfolder->getPath().'/nc.jpg'); + $file = $userfolder->get('nc.jpg'); + $file->touch(); $this->photoFileService->addPhotoNow($file, 'test'); - $filename = 'tests/test_files/nut.jpg'; - $handle = fopen($filename, 'rb'); - $content1 = fread($handle, filesize($filename)); - fclose($handle); - $file = $userfolder->newFile('nut.jpgg'); - $fp = $file->fopen('wb'); - fwrite($fp, $content1); - fclose($fp); - $file->touch(); - // rename - $file = $userfolder->get('nut.jpgg'); - $file->move($userfolder->getPath().'/nut.jpg'); - $file = $userfolder->get('nut.jpg'); - $file->touch(); - - // following section is not valid anymore - // TODO fix photo scan (or make it really better) and then adjust tests ;-) - $this->photoFileService->addPhotoNow($file, 'test'); + $filename = 'tests/test_files/nut.jpg'; + $handle = fopen($filename, 'rb'); + $content1 = fread($handle, filesize($filename)); + fclose($handle); + $file = $userfolder->newFile('nut.jpgg'); + $fp = $file->fopen('wb'); + fwrite($fp, $content1); + fclose($fp); + $file->touch(); + // rename + $file = $userfolder->get('nut.jpgg'); + $file->move($userfolder->getPath().'/nut.jpg'); + $file = $userfolder->get('nut.jpg'); + $file->touch(); + + // following section is not valid anymore + // TODO fix photo scan (or make it really better) and then adjust tests ;-) + $this->photoFileService->addPhotoNow($file, 'test'); $this->GeoPhotosService->clearCache(); - $resp = $this->photosController->getPhotos(); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertCount(1, $data); - $this->assertEquals('/nc.jpg', $data[0]->path); + $resp = $this->photosController->getPhotos(); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertCount(1, $data); + $this->assertEquals('/nc.jpg', $data[0]->path); //Test .nomedia respected $this->GeoPhotosService->clearCache(); @@ -243,13 +239,13 @@ public function testAddGetPhotos() { $this->assertEquals(0, count($data)); $file->delete(); - // non localized without track + // non localized without track $this->GeoPhotosService->clearCache(); - $resp = $this->photosController->getNonLocalizedPhotos(); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertCount(0, $data); + $resp = $this->photosController->getNonLocalizedPhotos(); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertCount(0, $data); // with track $filename = 'tests/test_files/testFile1_locationNut.gpx'; @@ -273,7 +269,7 @@ public function testAddGetPhotos() { $this->assertStringStartsWith('track:', array_key_first($data)); $dataForTrack = array_shift($data); $this->assertCount(1, $dataForTrack); - $this->assertEquals('/nut.jpg', $dataForTrack[0]->path); + $this->assertEquals('/nut.jpg', $dataForTrack[0]->path); //Test .nomedia respected $this->GeoPhotosService->clearCache(); @@ -315,19 +311,19 @@ public function testAddGetPhotos() { $this->assertEquals(0, count($data)); $file->delete(); - // place photos - $resp = $this->photosController->placePhotos(['/nut.jpg'], [1.2345], [9.8765]); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertCount(1, $data); + // place photos + $resp = $this->photosController->placePhotos(['/nut.jpg'], [1.2345], [9.8765]); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertCount(1, $data); $this->GeoPhotosService->clearCache(); - $resp = $this->photosController->getPhotos(); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertCount(2, $data); + $resp = $this->photosController->getPhotos(); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertCount(2, $data); $this->GeoPhotosService->clearCache(); $resp = $this->photosController->getNonLocalizedPhotos(); @@ -336,19 +332,19 @@ public function testAddGetPhotos() { $data = $resp->getData(); $this->assertCount(0, $data); - // reset coords - $resp = $this->photosController->resetPhotosCoords(['/nut.jpg']); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertCount(1, $data); + // reset coords + $resp = $this->photosController->resetPhotosCoords(['/nut.jpg']); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertCount(1, $data); $this->GeoPhotosService->clearCache(); - $resp = $this->photosController->getPhotos(); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertCount(1, $data); + $resp = $this->photosController->getPhotos(); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertCount(1, $data); //Test usage of cache adding photo $resp = $this->photosController->placePhotos(['/nut.jpg'], [1.2345], [9.8765]); @@ -371,6 +367,6 @@ public function testAddGetPhotos() { $data = $resp->getData(); $this->assertCount(0, $data); - } + } } diff --git a/tests/Unit/Controller/PublicFavoritePageControllerTest.php b/tests/Unit/Controller/PublicFavoritePageControllerTest.php index 903d0428f..fa9871352 100644 --- a/tests/Unit/Controller/PublicFavoritePageControllerTest.php +++ b/tests/Unit/Controller/PublicFavoritePageControllerTest.php @@ -25,104 +25,98 @@ use OC; use OC\AppFramework\Http; -use \OCA\Maps\AppInfo\Application; +use OCA\Maps\AppInfo\Application; use OCA\Maps\DB\FavoriteShareMapper; use OCA\Maps\Service\FavoritesService; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\IAppContainer; -use \OCP\IServerContainer; +use OCP\IServerContainer; use PHPUnit\Framework\TestCase; +class PublicFavoritePageControllerTest extends TestCase { + /* @var PublicFavoritePageController */ + private $publicPageController; -class PublicFavoritePageControllerTest extends TestCase -{ - /* @var PublicFavoritePageController */ - private $publicPageController; + private $config; - private $config; + /* @var Application */ + private $app; - /* @var Application */ - private $app; + /* @var IAppContainer */ + private $container; - /* @var IAppContainer */ - private $container; + /* @var FavoritesService */ + private $favoritesService; - /* @var FavoritesService */ - private $favoritesService; + /* @var FavoriteShareMapper */ + private $favoriteShareMapper; - /* @var FavoriteShareMapper */ - private $favoriteShareMapper; + protected function setUp(): void { + // Begin transaction + $db = OC::$server->query(\OCP\IDBConnection::class); + $db->beginTransaction(); - protected function setUp(): void - { - // Begin transaction - $db = OC::$server->query(\OCP\IDBConnection::class); - $db->beginTransaction(); + $this->app = new Application(); - $this->app = new Application(); + $this->container = $this->app->getContainer(); + $container = $this->container; - $this->container = $this->app->getContainer(); - $container = $this->container; + $appName = $container->query('AppName'); - $appName = $container->query('AppName'); + $this->favoritesService = new FavoritesService( + $container->query(IServerContainer::class)->getLogger(), + $container->query(IServerContainer::class)->getL10N($appName), + $container->query(IServerContainer::class)->getSecureRandom(), + $container->query(\OCP\IDBConnection::class) + ); - $this->favoritesService = new FavoritesService( - $container->query(IServerContainer::class)->getLogger(), - $container->query(IServerContainer::class)->getL10N($appName), - $container->query(IServerContainer::class)->getSecureRandom(), - $container->query(\OCP\IDBConnection::class) - ); + $this->favoriteShareMapper = new FavoriteShareMapper( + $container->query(\OCP\IDBConnection::class), + $container->query(IServerContainer::class)->getSecureRandom(), + $container->query(IServerContainer::class)->getRootFolder() + ); - $this->favoriteShareMapper = new FavoriteShareMapper( - $container->query(\OCP\IDBConnection::class), - $container->query(IServerContainer::class)->getSecureRandom(), - $container->query(IServerContainer::class)->getRootFolder() - ); + $requestMock = $this->getMockBuilder('OCP\IRequest')->getMock(); + $sessionMock = $this->getMockBuilder('OCP\ISession')->getMock(); - $requestMock = $this->getMockBuilder('OCP\IRequest')->getMock(); - $sessionMock = $this->getMockBuilder('OCP\ISession')->getMock(); + $this->config = $container->query(IServerContainer::class)->getConfig(); - $this->config = $container->query(IServerContainer::class)->getConfig(); + $this->publicPageController = new PublicFavoritePageController( + $appName, + $requestMock, + $sessionMock, + $this->config, + $container->query(\OCP\ILogger::class), + $this->favoriteShareMapper + ); + } - $this->publicPageController = new PublicFavoritePageController( - $appName, - $requestMock, - $sessionMock, - $this->config, - $container->query(\OCP\ILogger::class), - $this->favoriteShareMapper - ); - } + protected function tearDown(): void { + // Rollback transaction + $db = OC::$server->query(\OCP\IDBConnection::class); + $db->rollBack(); + } - protected function tearDown(): void - { - // Rollback transaction - $db = OC::$server->query(\OCP\IDBConnection::class); - $db->rollBack(); - } + public function testSharedFavoritesCategory() { + $categoryName = 'test908780'; + $testUserName = 'test'; - public function testSharedFavoritesCategory() - { - $categoryName = 'test908780'; - $testUserName = 'test'; + $this->favoritesService + ->addFavoriteToDB($testUserName, 'Test', 0, 0, $categoryName, '', null); + $share = $this->favoriteShareMapper->create($testUserName, $categoryName); - $this->favoritesService - ->addFavoriteToDB($testUserName, "Test", 0, 0, $categoryName, "", null); - $share = $this->favoriteShareMapper->create($testUserName, $categoryName); + $result = $this->publicPageController->sharedFavoritesCategory($share->getToken()); - $result = $this->publicPageController->sharedFavoritesCategory($share->getToken()); + // Assertions + $this->assertTrue($result instanceof TemplateResponse); + $this->assertEquals('public/favorites_index', $result->getTemplateName()); + } - // Assertions - $this->assertTrue($result instanceof TemplateResponse); - $this->assertEquals('public/favorites_index', $result->getTemplateName()); - } + public function testAccessRestrictionsForSharedFavoritesCategory() { + $result = $this->publicPageController->sharedFavoritesCategory('test8348985'); - public function testAccessRestrictionsForSharedFavoritesCategory() - { - $result = $this->publicPageController->sharedFavoritesCategory('test8348985'); - - $this->assertTrue($result instanceof DataResponse); - $this->assertEquals(Http::STATUS_NOT_FOUND, $result->getStatus()); - } + $this->assertTrue($result instanceof DataResponse); + $this->assertEquals(Http::STATUS_NOT_FOUND, $result->getStatus()); + } } diff --git a/tests/Unit/Controller/PublicFavoritesApiControllerTest.php b/tests/Unit/Controller/PublicFavoritesApiControllerTest.php index 345e08b2e..f9290af33 100644 --- a/tests/Unit/Controller/PublicFavoritesApiControllerTest.php +++ b/tests/Unit/Controller/PublicFavoritesApiControllerTest.php @@ -25,101 +25,98 @@ use OC; use OC\AppFramework\Http; -use \OCP\IServerContainer; use OCA\Maps\AppInfo\Application; use OCA\Maps\DB\FavoriteShare; use OCA\Maps\DB\FavoriteShareMapper; use OCA\Maps\Service\FavoritesService; +use OCP\IServerContainer; use PHPUnit\Framework\TestCase; +class PublicFavoritesApiControllerTest extends TestCase { + /* @var PublicFavoritesApiController */ + private $publicFavoritesApiController; -class PublicFavoritesApiControllerTest extends TestCase -{ - /* @var PublicFavoritesApiController */ - private $publicFavoritesApiController; + private $config; - private $config; + /* @var FavoritesService */ + private $favoritesService; - /* @var FavoritesService */ - private $favoritesService; + /* @var FavoriteShareMapper */ + private $favoriteShareMapper; - /* @var FavoriteShareMapper */ - private $favoriteShareMapper; + protected function setUp(): void { + // Begin transaction + $db = OC::$server->query(\OCP\IDBConnection::class); + $db->beginTransaction(); - protected function setUp(): void { - // Begin transaction - $db = OC::$server->query(\OCP\IDBConnection::class); - $db->beginTransaction(); + $container = (new Application())->getContainer(); - $container = (new Application())->getContainer(); + $appName = $container->query('AppName'); - $appName = $container->query('AppName'); + $requestMock = $this->getMockBuilder('OCP\IRequest')->getMock(); + $sessionMock = $this->getMockBuilder('OCP\ISession')->getMock(); - $requestMock = $this->getMockBuilder('OCP\IRequest')->getMock(); - $sessionMock = $this->getMockBuilder('OCP\ISession')->getMock(); + $this->config = $container->query(IServerContainer::class)->getConfig(); - $this->config = $container->query(IServerContainer::class)->getConfig(); + $this->favoritesService = new FavoritesService( + $container->query(IServerContainer::class)->getLogger(), + $container->query(IServerContainer::class)->getL10N($appName), + $container->query(IServerContainer::class)->getSecureRandom(), + $container->query(\OCP\IDBConnection::class) + ); - $this->favoritesService = new FavoritesService( - $container->query(IServerContainer::class)->getLogger(), - $container->query(IServerContainer::class)->getL10N($appName), - $container->query(IServerContainer::class)->getSecureRandom(), - $container->query(\OCP\IDBConnection::class) - ); + $this->favoriteShareMapper = new FavoriteShareMapper( + $container->query(\OCP\IDBConnection::class), + $container->query(IServerContainer::class)->getSecureRandom(), + $container->query(IserverContainer::class)->getRootFolder() + ); - $this->favoriteShareMapper = new FavoriteShareMapper( - $container->query(\OCP\IDBConnection::class), - $container->query(IServerContainer::class)->getSecureRandom(), - $container->query(IserverContainer::class)->getRootFolder() - ); + $this->publicFavoritesApiController = new PublicFavoritesApiController( + $appName, + $requestMock, + $sessionMock, + $this->favoritesService, + $this->favoriteShareMapper + ); + } - $this->publicFavoritesApiController = new PublicFavoritesApiController( - $appName, - $requestMock, - $sessionMock, - $this->favoritesService, - $this->favoriteShareMapper - ); - } + protected function tearDown(): void { + // Rollback transaction + $db = OC::$server->query(\OCP\IDBConnection::class); + $db->rollBack(); + } - protected function tearDown(): void - { - // Rollback transaction - $db = OC::$server->query(\OCP\IDBConnection::class); - $db->rollBack(); - } + public function testGetFavorites() { + $testUser = 'test099897'; + $categoryName = 'test89774590'; - public function testGetFavorites() { - $testUser = 'test099897'; - $categoryName = 'test89774590'; + $this->favoritesService + ->addFavoriteToDB($testUser, 'Test1', 0, 0, $categoryName, '', null); - $this->favoritesService - ->addFavoriteToDB($testUser, "Test1", 0, 0, $categoryName, "", null); + /* @var FavoriteShare */ + $share = $this->favoriteShareMapper->create($testUser, $categoryName); - /* @var FavoriteShare */ - $share = $this->favoriteShareMapper->create($testUser, $categoryName); + // Mock token sent by request + $this->publicFavoritesApiController->setToken($share->getToken()); - // Mock token sent by request - $this->publicFavoritesApiController->setToken($share->getToken()); + $response = $this->publicFavoritesApiController->getFavorites(); - $response = $this->publicFavoritesApiController->getFavorites(); + $this->assertEquals(Http::STATUS_OK, $response->getStatus()); - $this->assertEquals(Http::STATUS_OK, $response->getStatus()); + $data = $response->getData(); - $data = $response->getData(); + $this->assertIsArray($data); + $this->assertArrayHasKey('share', $data); + $this->assertArrayHasKey('favorites', $data); - $this->assertIsArray($data); - $this->assertArrayHasKey('share', $data); - $this->assertArrayHasKey('favorites', $data); + $this->assertEquals($testUser, $data['share']->getOwner()); + $this->assertEquals($categoryName, $data['share']->getCategory()); + $this->assertEquals($share->getToken(), $data['share']->getToken()); - $this->assertEquals($testUser, $data['share']->getOwner()); - $this->assertEquals($categoryName, $data['share']->getCategory()); - $this->assertEquals($share->getToken(), $data['share']->getToken()); + $this->assertEquals(1, count($data['favorites'])); - $this->assertEquals(1, count($data['favorites'])); - - $el = $data['favorites'][0]; - $this->assertEquals('Test1', $el['name']); - $this->assertEquals($categoryName, $el['category']); - } + $el = $data['favorites'][0]; + $this->assertEquals('Test1', $el['name']); + $this->assertEquals($categoryName, $el['category']); + } } diff --git a/tests/Unit/Controller/TracksControllerTest.php b/tests/Unit/Controller/TracksControllerTest.php index a9734a28c..447e73272 100644 --- a/tests/Unit/Controller/TracksControllerTest.php +++ b/tests/Unit/Controller/TracksControllerTest.php @@ -11,285 +11,279 @@ namespace OCA\Maps\Controller; -use \OCA\Maps\AppInfo\Application; -use OCP\DB\QueryBuilder\IQueryBuilder; -use \OCP\IServerContainer; -use OCA\Maps\Service\GeophotoService; -use OCA\Maps\Service\PhotofilesService; +use OCA\Maps\AppInfo\Application; use OCA\Maps\Service\TracksService; -use OCA\Maps\Service\DevicesService; -use OCA\Maps\DB\GeophotoMapper; -use OCP\AppFramework\Http\TemplateResponse; - +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IServerContainer; class TracksControllerTest extends \PHPUnit\Framework\TestCase { - private $appName; - private $request; - private $contacts; - - private $container; - private $config; - private $app; - - private $tracksController; - private $tracksController2; - private $utilsController; - - private $tracksService; - - public static function setUpBeforeClass(): void { - $app = new Application(); - $c = $app->getContainer(); - - $user = $c->getServer()->getUserManager()->get('test'); - $user2 = $c->getServer()->getUserManager()->get('test2'); - $user3 = $c->getServer()->getUserManager()->get('test3'); - $group = $c->getServer()->getGroupManager()->get('group1test'); - $group2 = $c->getServer()->getGroupManager()->get('group2test'); - - // CREATE DUMMY USERS - if ($user === null) { - $u1 = $c->getServer()->getUserManager()->createUser('test', 'tatotitoTUTU'); - $u1->setEMailAddress('toto@toto.net'); - } - if ($user2 === null) { - $u2 = $c->getServer()->getUserManager()->createUser('test2', 'plopinoulala000'); - } - if ($user2 === null) { - $u3 = $c->getServer()->getUserManager()->createUser('test3', 'yeyeahPASSPASS'); - } - if ($group === null) { - $c->getServer()->getGroupManager()->createGroup('group1test'); - $u1 = $c->getServer()->getUserManager()->get('test'); - $c->getServer()->getGroupManager()->get('group1test')->addUser($u1); - } - if ($group2 === null) { - $c->getServer()->getGroupManager()->createGroup('group2test'); - $u2 = $c->getServer()->getUserManager()->get('test2'); - $c->getServer()->getGroupManager()->get('group2test')->addUser($u2); - } - } - - protected function setUp(): void { - $this->appName = 'maps'; - $this->request = $this->getMockBuilder('\OCP\IRequest') - ->disableOriginalConstructor() - ->getMock(); - $this->contacts = $this->getMockBuilder('OCP\Contacts\IManager') - ->disableOriginalConstructor() - ->getMock(); - - $this->app = new Application(); - $this->container = $this->app->getContainer(); - $c = $this->container; - $this->config = $c->query(IServerContainer::class)->getConfig(); - - $this->rootFolder = $c->query(IServerContainer::class)->getRootFolder(); - - $this->tracksService = new TracksService( - $c->query(IServerContainer::class)->getLogger(), - $c->query(IServerContainer::class)->getL10N($c->query('AppName')), - $this->rootFolder, - $c->query(IServerContainer::class)->getShareManager(), - $c->query(IServerContainer::class)->query(\OCP\IDBConnection::class) - ); - - $this->tracksController = new TracksController( - $this->appName, - $this->request, - $c->query(IServerContainer::class), - $c->query(IServerContainer::class)->getConfig(), - $c->query(IServerContainer::class)->getShareManager(), - $c->getServer()->getAppManager(), - $c->getServer()->getUserManager(), - $c->getServer()->getGroupManager(), - $c->query(IServerContainer::class)->getL10N($c->query('AppName')), - $c->query(IServerContainer::class)->getLogger(), - $c->query(TracksService::class), - 'test', - ); - - $this->tracksController2 = new TracksController( - $this->appName, - $this->request, - $c->query(IServerContainer::class), - $c->query(IServerContainer::class)->getConfig(), - $c->query(IServerContainer::class)->getShareManager(), - $c->getServer()->getAppManager(), - $c->getServer()->getUserManager(), - $c->getServer()->getGroupManager(), - $c->query(IServerContainer::class)->getL10N($c->query('AppName')), - $c->query(IServerContainer::class)->getLogger(), - $c->query(TracksService::class), - 'test2', - ); - - $this->utilsController = new UtilsController( - $this->appName, - $this->request, - $c->query(IServerContainer::class)->getConfig(), - $c->getServer()->getAppManager(), + private $appName; + private $request; + private $contacts; + + private $container; + private $config; + private $app; + + private $tracksController; + private $tracksController2; + private $utilsController; + + private $tracksService; + + public static function setUpBeforeClass(): void { + $app = new Application(); + $c = $app->getContainer(); + + $user = $c->getServer()->getUserManager()->get('test'); + $user2 = $c->getServer()->getUserManager()->get('test2'); + $user3 = $c->getServer()->getUserManager()->get('test3'); + $group = $c->getServer()->getGroupManager()->get('group1test'); + $group2 = $c->getServer()->getGroupManager()->get('group2test'); + + // CREATE DUMMY USERS + if ($user === null) { + $u1 = $c->getServer()->getUserManager()->createUser('test', 'tatotitoTUTU'); + $u1->setEMailAddress('toto@toto.net'); + } + if ($user2 === null) { + $u2 = $c->getServer()->getUserManager()->createUser('test2', 'plopinoulala000'); + } + if ($user2 === null) { + $u3 = $c->getServer()->getUserManager()->createUser('test3', 'yeyeahPASSPASS'); + } + if ($group === null) { + $c->getServer()->getGroupManager()->createGroup('group1test'); + $u1 = $c->getServer()->getUserManager()->get('test'); + $c->getServer()->getGroupManager()->get('group1test')->addUser($u1); + } + if ($group2 === null) { + $c->getServer()->getGroupManager()->createGroup('group2test'); + $u2 = $c->getServer()->getUserManager()->get('test2'); + $c->getServer()->getGroupManager()->get('group2test')->addUser($u2); + } + } + + protected function setUp(): void { + $this->appName = 'maps'; + $this->request = $this->getMockBuilder('\OCP\IRequest') + ->disableOriginalConstructor() + ->getMock(); + $this->contacts = $this->getMockBuilder('OCP\Contacts\IManager') + ->disableOriginalConstructor() + ->getMock(); + + $this->app = new Application(); + $this->container = $this->app->getContainer(); + $c = $this->container; + $this->config = $c->query(IServerContainer::class)->getConfig(); + + $this->rootFolder = $c->query(IServerContainer::class)->getRootFolder(); + + $this->tracksService = new TracksService( + $c->query(IServerContainer::class)->getLogger(), + $c->query(IServerContainer::class)->getL10N($c->query('AppName')), + $this->rootFolder, + $c->query(IServerContainer::class)->getShareManager(), + $c->query(IServerContainer::class)->query(\OCP\IDBConnection::class) + ); + + $this->tracksController = new TracksController( + $this->appName, + $this->request, + $c->query(IServerContainer::class), + $c->query(IServerContainer::class)->getConfig(), + $c->query(IServerContainer::class)->getShareManager(), + $c->getServer()->getAppManager(), + $c->getServer()->getUserManager(), + $c->getServer()->getGroupManager(), + $c->query(IServerContainer::class)->getL10N($c->query('AppName')), + $c->query(IServerContainer::class)->getLogger(), + $c->query(TracksService::class), + 'test', + ); + + $this->tracksController2 = new TracksController( + $this->appName, + $this->request, + $c->query(IServerContainer::class), + $c->query(IServerContainer::class)->getConfig(), + $c->query(IServerContainer::class)->getShareManager(), + $c->getServer()->getAppManager(), + $c->getServer()->getUserManager(), + $c->getServer()->getGroupManager(), + $c->query(IServerContainer::class)->getL10N($c->query('AppName')), + $c->query(IServerContainer::class)->getLogger(), + $c->query(TracksService::class), + 'test2', + ); + + $this->utilsController = new UtilsController( + $this->appName, + $this->request, + $c->query(IServerContainer::class)->getConfig(), + $c->getServer()->getAppManager(), $this->rootFolder, - 'test' - ); - - $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); - - // delete first - if ($userfolder->nodeExists('testFile1.gpx')) { - //echo "DELETE\n"; - $file = $userfolder->get('testFile1.gpx'); - $file->delete(); - } - // delete db - $qb = $c->query(IServerContainer::class)->query(\OCP\IDBConnection::class)->getQueryBuilder(); - $qb->delete('maps_tracks') - ->where( - $qb->expr()->eq('user_id', $qb->createNamedParameter('test', IQueryBuilder::PARAM_STR)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - - public static function tearDownAfterClass(): void { - //$app = new Application(); - //$c = $app->getContainer(); - //$user = $c->getServer()->getUserManager()->get('test'); - //$user->delete(); - //$user = $c->getServer()->getUserManager()->get('test2'); - //$user->delete(); - //$user = $c->getServer()->getUserManager()->get('test3'); - //$user->delete(); - //$c->getServer()->getGroupManager()->get('group1test')->delete(); - //$c->getServer()->getGroupManager()->get('group2test')->delete(); - } - - protected function tearDown(): void { - // in case there was a failure and something was not deleted - $c = $this->app->getContainer(); - - $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); - // delete files - if ($userfolder->nodeExists('testFile1.gpx')) { - $file = $userfolder->get('testFile1.gpx'); - $file->delete(); - } - // delete db - $qb = $c->query(IServerContainer::class)->query(\OCP\IDBConnection::class)->getQueryBuilder(); - $qb->delete('maps_tracks') - ->where( - $qb->expr()->eq('user_id', $qb->createNamedParameter('test', IQueryBuilder::PARAM_STR)) - ); - $req = $qb->execute(); - $qb = $qb->resetQueryParts(); - } - - public function testAddGetTracks() { - $c = $this->app->getContainer(); - - $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); - - $filename = 'tests/test_files/testFile1.gpx'; - $content1 = file_get_contents($filename); - $file = $userfolder->newFile('testFile1.gpxx'); - $file->putContent($content1); - //$file->touch(); - - $file = $userfolder->get('testFile1.gpxx'); - $file->move($userfolder->getPath().'/testFile1.gpx'); - //echo 'I MOVE TO '.$userfolder->getPath().'/testFile1.gpx'."\n"; - $file = $userfolder->get('testFile1.gpx'); - $file->touch(); - - $resp = $this->tracksController->getTracks(); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $foundTestFile = false; - foreach ($data as $k => $v) { - if ($v['file_path'] === '/testFile1.gpx') { - $foundTestFile = true; - break; - } - } - $this->assertEquals(true, count($data) > 0); - $this->assertEquals(true, $foundTestFile); - - foreach ($this->tracksService->rescan('test') as $path) { - //echo $path."\n"; - } - - $resp = $this->tracksController->getTracks(); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $foundTestFile = false; - //var_dump($data); - $trackId = null; - foreach ($data as $k => $v) { - if ($v['file_path'] === '/testFile1.gpx') { - $foundTestFile = true; - $trackId = $v['id']; - $this->assertEquals(true, $v['color'] === null); - break; - } - } - $this->assertEquals(true, count($data) > 0); - $this->assertEquals(true, $foundTestFile); - - // track content - $resp = $this->tracksController->getTrackFileContent($trackId); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals(true, $content1 === $data['content']); - $meta = $data['metadata']; - $this->assertEquals(true, strlen($meta) > 0); - - // to get stored metadata - $resp = $this->tracksController->getTrackFileContent($trackId); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals(true, $content1 === $data['content']); - $this->assertEquals(true, $meta === $data['metadata']); - - // file that does not exist - $resp = $this->tracksController->getTrackFileContent(0); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('File not found', $data); - - // edit track - $resp = $this->tracksController->editTrack($trackId, '#002244', null, null); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $this->assertEquals('EDITED', $data); - - // check new color - $resp = $this->tracksController->getTracks(); - $status = $resp->getStatus(); - $this->assertEquals(200, $status); - $data = $resp->getData(); - $foundTestFile = false; - foreach ($data as $k => $v) { - if ($v['file_path'] === '/testFile1.gpx') { - $foundTestFile = true; - $this->assertEquals(true, $v['color'] === '#002244'); - break; - } - } - $this->assertEquals(true, count($data) > 0); - $this->assertEquals(true, $foundTestFile); - - // edit track that does not exist - $resp = $this->tracksController->editTrack(0, '#002244', null, null); - $status = $resp->getStatus(); - $this->assertEquals(400, $status); - $data = $resp->getData(); - $this->assertEquals('No such track', $data); - } + 'test' + ); + + $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); + + // delete first + if ($userfolder->nodeExists('testFile1.gpx')) { + //echo "DELETE\n"; + $file = $userfolder->get('testFile1.gpx'); + $file->delete(); + } + // delete db + $qb = $c->query(IServerContainer::class)->query(\OCP\IDBConnection::class)->getQueryBuilder(); + $qb->delete('maps_tracks') + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter('test', IQueryBuilder::PARAM_STR)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + + public static function tearDownAfterClass(): void { + //$app = new Application(); + //$c = $app->getContainer(); + //$user = $c->getServer()->getUserManager()->get('test'); + //$user->delete(); + //$user = $c->getServer()->getUserManager()->get('test2'); + //$user->delete(); + //$user = $c->getServer()->getUserManager()->get('test3'); + //$user->delete(); + //$c->getServer()->getGroupManager()->get('group1test')->delete(); + //$c->getServer()->getGroupManager()->get('group2test')->delete(); + } + + protected function tearDown(): void { + // in case there was a failure and something was not deleted + $c = $this->app->getContainer(); + + $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); + // delete files + if ($userfolder->nodeExists('testFile1.gpx')) { + $file = $userfolder->get('testFile1.gpx'); + $file->delete(); + } + // delete db + $qb = $c->query(IServerContainer::class)->query(\OCP\IDBConnection::class)->getQueryBuilder(); + $qb->delete('maps_tracks') + ->where( + $qb->expr()->eq('user_id', $qb->createNamedParameter('test', IQueryBuilder::PARAM_STR)) + ); + $req = $qb->execute(); + $qb = $qb->resetQueryParts(); + } + + public function testAddGetTracks() { + $c = $this->app->getContainer(); + + $userfolder = $this->container->query(IServerContainer::class)->getUserFolder('test'); + + $filename = 'tests/test_files/testFile1.gpx'; + $content1 = file_get_contents($filename); + $file = $userfolder->newFile('testFile1.gpxx'); + $file->putContent($content1); + //$file->touch(); + + $file = $userfolder->get('testFile1.gpxx'); + $file->move($userfolder->getPath().'/testFile1.gpx'); + //echo 'I MOVE TO '.$userfolder->getPath().'/testFile1.gpx'."\n"; + $file = $userfolder->get('testFile1.gpx'); + $file->touch(); + + $resp = $this->tracksController->getTracks(); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $foundTestFile = false; + foreach ($data as $k => $v) { + if ($v['file_path'] === '/testFile1.gpx') { + $foundTestFile = true; + break; + } + } + $this->assertEquals(true, count($data) > 0); + $this->assertEquals(true, $foundTestFile); + + foreach ($this->tracksService->rescan('test') as $path) { + //echo $path."\n"; + } + + $resp = $this->tracksController->getTracks(); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $foundTestFile = false; + //var_dump($data); + $trackId = null; + foreach ($data as $k => $v) { + if ($v['file_path'] === '/testFile1.gpx') { + $foundTestFile = true; + $trackId = $v['id']; + $this->assertEquals(true, $v['color'] === null); + break; + } + } + $this->assertEquals(true, count($data) > 0); + $this->assertEquals(true, $foundTestFile); + + // track content + $resp = $this->tracksController->getTrackFileContent($trackId); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals(true, $content1 === $data['content']); + $meta = $data['metadata']; + $this->assertEquals(true, strlen($meta) > 0); + + // to get stored metadata + $resp = $this->tracksController->getTrackFileContent($trackId); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals(true, $content1 === $data['content']); + $this->assertEquals(true, $meta === $data['metadata']); + + // file that does not exist + $resp = $this->tracksController->getTrackFileContent(0); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('File not found', $data); + + // edit track + $resp = $this->tracksController->editTrack($trackId, '#002244', null, null); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $this->assertEquals('EDITED', $data); + + // check new color + $resp = $this->tracksController->getTracks(); + $status = $resp->getStatus(); + $this->assertEquals(200, $status); + $data = $resp->getData(); + $foundTestFile = false; + foreach ($data as $k => $v) { + if ($v['file_path'] === '/testFile1.gpx') { + $foundTestFile = true; + $this->assertEquals(true, $v['color'] === '#002244'); + break; + } + } + $this->assertEquals(true, count($data) > 0); + $this->assertEquals(true, $foundTestFile); + + // edit track that does not exist + $resp = $this->tracksController->editTrack(0, '#002244', null, null); + $status = $resp->getStatus(); + $this->assertEquals(400, $status); + $data = $resp->getData(); + $this->assertEquals('No such track', $data); + } } diff --git a/tests/Unit/Helper/ExifGeoDataTest.php b/tests/Unit/Helper/ExifGeoDataTest.php index 3a31c9f18..46d66d498 100644 --- a/tests/Unit/Helper/ExifGeoDataTest.php +++ b/tests/Unit/Helper/ExifGeoDataTest.php @@ -3,45 +3,43 @@ namespace OCA\Maps\Helper; use PHPUnit\Framework\TestCase; -use OCA\Maps\Helper\ExifGeoData; -use OCA\Maps\Helper\ExifDataNoLocationException; class ExifGeoDataTest extends TestCase { public function imageWithDateAndLocationProvider(): array { return [ - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation1.JPG", 1311984000 + 7200, 47.071717, 10.339557], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation2.JPG", 1312156800 + 7200, 46.862350, 10.916452], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation3.JPG", 1312070400 + 7200, 47.069058, 10.329370], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation4.JPG", 1312070400 + 7200, 47.059160, 10.312354], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation5.JPG", 1568101093 + 7200, 47.357735, 11.177585], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation6.JPG", 1577630208 + 3600, 50.083045, 9.986018], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation7.jpg", 1568999599 + 7200, 49.420833, 11.114444], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation8.JPG", 1501431401 + 7200, 45.306983, 10.700902], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation9.JPG", 1302998400 + 7200, 52.363055, 4.903418], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation10.JPG", 1501238375 + 7200, 46.388742, 11.266598], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation11.JPG", 1501567361 + 7200, 44.827830, 10.956387], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation12.JPG", 1501591333 + 7200, 44.528283, 11.262207], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation13.jpg", 1640083235 + 3600, 54.359561, 10.017325], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation14.jpg", 1559327910 + 7200, 52.976844, 12.988281], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation15.jpg", 1559332394 + 7200, 52.983697, 12.935217], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation16.jpeg", 1593458542 + 7200, 62.733947, 6.779617], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation17.jpeg", 1593458620 + 7200, 62.733769, 6.777794], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation18.jpeg", 1596136867 + 7200, 54.350891, 9.903506], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation19.jpeg", 1596136833 + 7200, 54.350894, 9.903505], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation20.jpeg", 1592913150 + 7200, 61.351753, 6.519107], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation21.jpg", 1653565075 + 7200, 48.704331, 8.418475], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation22.jpeg", 1593890841 + 7200, 62.735419, 7.155311], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation23.jpeg", 1592904886 + 7200, 61.217086, 6.558886], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation24.jpeg", 1592677991 + 7200, 60.427481, 6.548446], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation25.jpeg", 1592650395 + 7200, 59.860523, 6.696346], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation26.jpeg", 1592770386 + 7200, 60.594022, 6.581317], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation27.jpeg", 1592654095 + 7200, 60.033561, 6.563068], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation28.jpg", 1595326357 + 7200, 59.852992, 6.714458], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation29.jpg", 1594918175 + 7200, 57.595925, 9.976864], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation30.jpg", 1595418724 + 7200, 60.669492, 6.807386], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation31.jpg", 1594934141 + 7200, 57.801164, 8.314269], - ["tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation32.jpeg", 1595629060 + 7200, 59.598981, 9.677297], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation1.JPG', 1311984000 + 7200, 47.071717, 10.339557], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation2.JPG', 1312156800 + 7200, 46.862350, 10.916452], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation3.JPG', 1312070400 + 7200, 47.069058, 10.329370], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation4.JPG', 1312070400 + 7200, 47.059160, 10.312354], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation5.JPG', 1568101093 + 7200, 47.357735, 11.177585], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation6.JPG', 1577630208 + 3600, 50.083045, 9.986018], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation7.jpg', 1568999599 + 7200, 49.420833, 11.114444], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation8.JPG', 1501431401 + 7200, 45.306983, 10.700902], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation9.JPG', 1302998400 + 7200, 52.363055, 4.903418], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation10.JPG', 1501238375 + 7200, 46.388742, 11.266598], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation11.JPG', 1501567361 + 7200, 44.827830, 10.956387], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation12.JPG', 1501591333 + 7200, 44.528283, 11.262207], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation13.jpg', 1640083235 + 3600, 54.359561, 10.017325], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation14.jpg', 1559327910 + 7200, 52.976844, 12.988281], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation15.jpg', 1559332394 + 7200, 52.983697, 12.935217], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation16.jpeg', 1593458542 + 7200, 62.733947, 6.779617], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation17.jpeg', 1593458620 + 7200, 62.733769, 6.777794], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation18.jpeg', 1596136867 + 7200, 54.350891, 9.903506], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation19.jpeg', 1596136833 + 7200, 54.350894, 9.903505], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation20.jpeg', 1592913150 + 7200, 61.351753, 6.519107], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation21.jpg', 1653565075 + 7200, 48.704331, 8.418475], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation22.jpeg', 1593890841 + 7200, 62.735419, 7.155311], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation23.jpeg', 1592904886 + 7200, 61.217086, 6.558886], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation24.jpeg', 1592677991 + 7200, 60.427481, 6.548446], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation25.jpeg', 1592650395 + 7200, 59.860523, 6.696346], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation26.jpeg', 1592770386 + 7200, 60.594022, 6.581317], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation27.jpeg', 1592654095 + 7200, 60.033561, 6.563068], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation28.jpg', 1595326357 + 7200, 59.852992, 6.714458], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation29.jpg', 1594918175 + 7200, 57.595925, 9.976864], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation30.jpg', 1595418724 + 7200, 60.669492, 6.807386], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation31.jpg', 1594934141 + 7200, 57.801164, 8.314269], + ['tests/test_files/Photos/WithDateAndLocation/imageWithDateAndLocation32.jpeg', 1595629060 + 7200, 59.598981, 9.677297], ]; } /** @@ -52,13 +50,13 @@ public function testImagesWithDateAndLocation(string $path, int $date, float $la $exif_geo_data->validate(true); $this->assertEquals($date, $exif_geo_data->dateTaken); //This is the same upto ~55cm - $this->assertEqualsWithDelta($lat, $exif_geo_data->lat, 0.000005); + $this->assertEqualsWithDelta($lat, $exif_geo_data->lat, 0.000005); $this->assertEqualsWithDelta($lng, $exif_geo_data->lng, 0.000005); } public function imageWithZeroIslandProvider(): array { return [ - ["tests/test_files/Photos/ZeroIsland/imageZeroIsland1.JPG", 1653829180 + 7200], + ['tests/test_files/Photos/ZeroIsland/imageZeroIsland1.JPG', 1653829180 + 7200], ]; } /** @@ -66,7 +64,7 @@ public function imageWithZeroIslandProvider(): array { */ public function testImagesWithZeroIslandException(string $path, int $date) { $this->expectException(ExifDataNoLocationException::class); - $this->expectExceptionMessage("Zero island is not valid"); + $this->expectExceptionMessage('Zero island is not valid'); $exif_geo_data = ExifGeoData::get($path); $exif_geo_data->validate(true); } @@ -78,11 +76,11 @@ public function testImagesWithZeroIslandGeoDataNull(string $path, int $date) { $exif_geo_data = ExifGeoData::get($path); try { $exif_geo_data->validate(true); - $this->assertEquals(true,false); + $this->assertEquals(true, false); } catch (ExifDataNoLocationException $e) { $this->assertEquals($date, $exif_geo_data->dateTaken); //This is the same upto ~55cm - $this->assertEqualsWithDelta(null, $exif_geo_data->lat, 0.000005); + $this->assertEqualsWithDelta(null, $exif_geo_data->lat, 0.000005); $this->assertEqualsWithDelta(null, $exif_geo_data->lng, 0.000005); } } @@ -95,7 +93,7 @@ public function testImagesWithZeroIsland(string $path, int $date) { $exif_geo_data->validate(false); $this->assertEquals($date, $exif_geo_data->dateTaken); //This is the same upto ~55cm - $this->assertEqualsWithDelta(0.0, $exif_geo_data->lat, 0.000005); + $this->assertEqualsWithDelta(0.0, $exif_geo_data->lat, 0.000005); $this->assertEqualsWithDelta(0.0, $exif_geo_data->lng, 0.000005); } } From ef5b04cfa9069b4584027b6497a80141574d8dcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Sat, 14 Sep 2024 20:25:03 +0200 Subject: [PATCH 05/10] chore: Add previous commit to .git-blame-ignore-revs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- .git-blame-ignore-revs | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 000000000..9f0cfe398 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,7 @@ +# .git-blame-ignore-revs + +# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors +# SPDX-License-Identifier: AGPL-3.0-or-later + +# Run of cs:fix +b059d12c92bc2dbfa9346ecad1c47cee1a5cb0c7 From c1eff88f61490dc6cfca48697aba2bfcf96af903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Sat, 14 Sep 2024 20:46:05 +0200 Subject: [PATCH 06/10] chore: Add missing parts in composer.json thanks to Louis awesome documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- composer.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e5ba42059..b4537327e 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,13 @@ "test:integration": "phpunit -c tests/phpunit.integration.xml --fail-on-warning", "test:integration:dev": "phpunit -c tests/phpunit.integration.xml --no-coverage --order-by=defects --stop-on-defect --fail-on-warning --stop-on-error --stop-on-failure", "test:unit": "phpunit -c tests/phpunit.unit.xml --fail-on-warning", - "test:unit:dev": "phpunit -c tests/phpunit.unit.xml --no-coverage --order-by=defects --stop-on-defect --fail-on-warning --stop-on-error --stop-on-failure" + "test:unit:dev": "phpunit -c tests/phpunit.unit.xml --no-coverage --order-by=defects --stop-on-defect --fail-on-warning --stop-on-error --stop-on-failure", + "post-install-cmd": [ + "[ $COMPOSER_DEV_MODE -eq 0 ] || composer bin all install --ansi" + ], + "post-update-cmd": [ + "[ $COMPOSER_DEV_MODE -eq 0 ] || composer bin all update --ansi" + ] }, "autoload": { "files": [ @@ -23,6 +29,12 @@ "OCA\\Maps\\": "./lib/" } }, + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + } + }, "config": { "allow-plugins": { "bamarni/composer-bin-plugin": true From 4c07dfb3c9368dd0928ded13e9cf03d435abdbbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Sat, 14 Sep 2024 21:04:12 +0200 Subject: [PATCH 07/10] chore: Add missing lint script in composer.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index b4537327e..00612ab96 100644 --- a/composer.json +++ b/composer.json @@ -10,6 +10,7 @@ "scripts": { "cs:fix": "php-cs-fixer fix", "cs:check": "php-cs-fixer fix --dry-run --diff", + "lint": "find . -name \\*.php -not -path './vendor/*' -print0 | xargs -0 -n1 php -l", "test:integration": "phpunit -c tests/phpunit.integration.xml --fail-on-warning", "test:integration:dev": "phpunit -c tests/phpunit.integration.xml --no-coverage --order-by=defects --stop-on-defect --fail-on-warning --stop-on-error --stop-on-failure", "test:unit": "phpunit -c tests/phpunit.unit.xml --fail-on-warning", From e5f4243f1b605d9bd7d82af7dad0f6bf4cfa7655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Sat, 14 Sep 2024 21:11:36 +0200 Subject: [PATCH 08/10] chore: change composer version used by unit test workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- .github/workflows/test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d1385a2cf..74e46e236 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,6 @@ jobs: uses: shivammathur/setup-php@master with: php-version: ${{ matrix.php-versions }} - tools: composer:v1 extensions: ctype,curl,dom,gd,iconv,intl,json,mbstring,openssl,posix,sqlite,xml,zip,gmp coverage: xdebug - name: Checkout Nextcloud From a85a2328c626ee97b0ab4c0e26ff920e3b46a336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Sat, 14 Sep 2024 21:22:53 +0200 Subject: [PATCH 09/10] chore: fix order of tags in info.xml to respect schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- appinfo/info.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/appinfo/info.xml b/appinfo/info.xml index 2e1f559c6..a80b04d86 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -20,6 +20,9 @@ Arne Hamann Jan C. Borchardt Maps + + + integration multimedia organization @@ -32,18 +35,18 @@ https://raw.githubusercontent.com/nextcloud/maps/master/screenshots/screenshot2.png https://raw.githubusercontent.com/nextcloud/maps/master/screenshots/screenshot3.png + exif - + + OCA\Maps\Migration\RegisterMimeType + OCA\Maps\Migration\InstallScan OCA\Maps\Migration\RegisterMimeType - - OCA\Maps\Migration\RegisterMimeType - OCA\Maps\Migration\UnregisterMimeType @@ -63,7 +66,4 @@ app.svg - - - From 47548fc1743abc799148ceb47bac4674d7aac84b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Sat, 14 Sep 2024 21:29:11 +0200 Subject: [PATCH 10/10] chore: fix post-migration repair step naming in info.xml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- appinfo/info.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appinfo/info.xml b/appinfo/info.xml index a80b04d86..2990fef7c 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -40,9 +40,9 @@ - + OCA\Maps\Migration\RegisterMimeType - + OCA\Maps\Migration\InstallScan OCA\Maps\Migration\RegisterMimeType