diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cdc7851 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.idea +*.iml +/vendor/ +/build/ +node_modules/ +/.php-cs-fixer.cache +js/*hot-update.* diff --git a/.l10nignore b/.l10nignore deleted file mode 100644 index e8ee91a..0000000 --- a/.l10nignore +++ /dev/null @@ -1,91 +0,0 @@ -js/lib/typearray.js -js/lib/typearray.min.js -js/lib/wgxpath.install.js -vendor/bitjs/io/bytebuffer.js -vendor/bitjs/io/bytestream.js -vendor/bitjs/io/bitstream.js -vendor/bitjs/archive/unzip.js -vendor/bitjs/archive/untar.js -vendor/bitjs/archive/unrar.js -vendor/bitjs/archive/rarvm.js -vendor/bitjs/archive/archive.js -vendor/pixastic/pixastic_combined.js -vendor/pixastic/pixastic.worker.js -vendor/pixastic/pixastic.effects.js -vendor/pixastic/pixastic.worker.control.js -vendor/pixastic/pixastic.js -vendor/icomoon/style.css -vendor/icomoon/fonts/icomoon.svg -vendor/icomoon/fonts/icomoon.woff -vendor/icomoon/fonts/icomoon.ttf -vendor/icomoon/fonts/icomoon.eot -vendor/bartaz/jquery.highlight.js -vendor/sindresorhus/screenfull.js -vendor/jquery/put-delete.js -vendor/epubjs/libs/zip.min.js -vendor/epubjs/libs/jquery.min.js -vendor/epubjs/libs/screenfull.min.js -vendor/epubjs/hooks.min.map -vendor/epubjs/epub.min.js -vendor/epubjs/css/popup.css -vendor/epubjs/css/main.css -vendor/epubjs/css/normalize.css -vendor/epubjs/css/sidebar.css -vendor/epubjs/css/font/fontello.svg -vendor/epubjs/css/font/fontello.woff -vendor/epubjs/css/font/fontello.eot -vendor/epubjs/css/font/fontello.ttf -vendor/epubjs/css/annotations.css -vendor/epubjs/css/idevice.css -vendor/epubjs/epub.main.css -vendor/epubjs/reader.min.js -vendor/epubjs/epub.min.map -vendor/epubjs/hooks.min.js -vendor/epubjs/hooks/default/smartimages.js -vendor/epubjs/hooks/extensions/highlight.js -vendor/epubjs/reader.min.map -vendor/bgrins/spectrum.js -vendor/bgrins/spectrum.css -vendor/cbrjs/css/cbr.css -vendor/cbrjs/css/idevice.css -vendor/cbrjs/cbr.js -vendor/cbrjs/img/loading.gif -vendor/pdfjs/css/popup.css -vendor/pdfjs/css/main.css -vendor/pdfjs/css/annotation_layer_builder.css -vendor/pdfjs/css/normalize.css -vendor/pdfjs/css/sidebar.css -vendor/pdfjs/css/annotations.css -vendor/pdfjs/css/text_layer_builder.css -vendor/pdfjs/css/idevice.css -vendor/pdfjs/css/images/annotation-insert.svg -vendor/pdfjs/css/images/annotation-newparagraph.svg -vendor/pdfjs/css/images/annotation-key.svg -vendor/pdfjs/css/images/annotation-check.svg -vendor/pdfjs/css/images/annotation-paragraph.svg -vendor/pdfjs/css/images/annotation-help.svg -vendor/pdfjs/css/images/annotation-noicon.svg -vendor/pdfjs/css/images/annotation-comment.svg -vendor/pdfjs/css/images/annotation-note.svg -vendor/pdfjs/pdf.reader.js -vendor/pdfjs/controllers/textlayer_controller.js -vendor/pdfjs/controllers/sidebar_controller.js -vendor/pdfjs/controllers/outline_controller.js -vendor/pdfjs/controllers/styles_controller.js -vendor/pdfjs/controllers/notes_controller.js -vendor/pdfjs/controllers/settings_controller.js -vendor/pdfjs/controllers/meta_controller.js -vendor/pdfjs/controllers/reader_controller.js -vendor/pdfjs/controllers/bookmarks_controller.js -vendor/pdfjs/controllers/progress_controller.js -vendor/pdfjs/controllers/toc_controller.js -vendor/pdfjs/controllers/search_controller.js -vendor/pdfjs/controllers/controls_controller.js -vendor/pdfjs/controllers/annotationlayer_controller.js -vendor/pdfjs/controllers/textlayer_controller.js.simple -vendor/pdfjs/services/eventbus_service.js -vendor/pdfjs/services/simple_link_service.js -vendor/pdfjs/services/link_service.js -vendor/pdfjs/lib/pdf.worker.js -vendor/pdfjs/lib/text_layer_builder.js -vendor/pdfjs/lib/pdf.js diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..f7bbdd8 --- /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/appinfo/app.php b/appinfo/app.php deleted file mode 100644 index cf3b4ee..0000000 --- a/appinfo/app.php +++ /dev/null @@ -1,21 +0,0 @@ -getL10N('epubreader'); - -\OCA\Epubreader\Hooks::register(); -Util::addscript('epubreader', 'plugin'); diff --git a/appinfo/info.xml b/appinfo/info.xml index bffaa21..fb5f44f 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -29,7 +29,7 @@ See [README] for more exhaustive information on features and potential misfeatur [README]: https://github.com/e-alfred/epubreader/blob/master/epubreader/README.md ]]> - 1.4.7 + 1.4.8 agpl Frank de Lange e-alfred @@ -46,10 +46,13 @@ See [README] for more exhaustive information on features and potential misfeatur https://github.com/e-alfred/epubreader/blob/master/screenshots/photo_2017-03-15_17-22-00.jpg?raw=true https://github.com/e-alfred/epubreader/blob/master/screenshots/photo_2017-03-15_17-22-02.jpg?raw=true - + OCA\Epubreader\Settings\Personal OCA\Epubreader\Settings\PersonalSection + + + diff --git a/appinfo/routes.php b/appinfo/routes.php index f70c426..27cdf81 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -11,31 +11,26 @@ */ return ['routes' => [ - // Page - ['name' => 'page#showReader', 'url' => '/', 'verb' => 'GET'], + // Page + ['name' => 'page#showReader', 'url' => '/', 'verb' => 'GET'], - // Bookmarks - ['name' => 'bookmark#get_cursor', 'url' => '/bookmark/cursor/{fileId}', 'verb' => 'GET'], - ['name' => 'bookmark#set_cursor', 'url' => '/bookmark/cursor', 'verb' => 'POST'], - ['name' => 'bookmark#delete_cursor', 'url' => '/bookmark/cursor/{fileId}', 'verb' => 'DELETE'], - ['name' => 'bookmark#get', 'url' => '/bookmark/{fileId}/{name}', 'verb' => 'GET', 'defaults' => ['name' => '']], - ['name' => 'bookmark#get', 'url' => '/bookmark/{fileId}/{type}/{name}', 'verb' => 'GET', 'defaults' => ['name' => '']], - ['name' => 'bookmark#set', 'url' => '/bookmark', 'verb' => 'POST'], - ['name' => 'bookmark#delete', 'url' => '/bookmark/{fileId}/{name}', 'verb' => 'DELETE'], + // Bookmarks + ['name' => 'bookmark#get_cursor', 'url' => '/bookmark/cursor/{fileId}', 'verb' => 'GET'], + ['name' => 'bookmark#set_cursor', 'url' => '/bookmark/cursor', 'verb' => 'POST'], + ['name' => 'bookmark#delete_cursor', 'url' => '/bookmark/cursor/{fileId}', 'verb' => 'DELETE'], + ['name' => 'bookmark#get', 'url' => '/bookmark/{fileId}/{name}', 'verb' => 'GET', 'defaults' => ['name' => '']], + ['name' => 'bookmark#get', 'url' => '/bookmark/{fileId}/{type}/{name}', 'verb' => 'GET', 'defaults' => ['name' => '']], + ['name' => 'bookmark#set', 'url' => '/bookmark', 'verb' => 'POST'], + ['name' => 'bookmark#delete', 'url' => '/bookmark/{fileId}/{name}', 'verb' => 'DELETE'], - // Metadata - ['name' => 'metadata#get', 'url' => '/metadata/{fileId}/{name}', 'verb' => 'GET', 'defaults' => ['name' => '']], - ['name' => 'metadata#set', 'url' => '/metadata/{fileId}/{name}/{value}', 'verb' => 'POST'], + // Preferences + ['name' => 'preference#get_default', 'url' => '/preference/default/{scope}/{name}', 'verb' => 'GET', 'defaults' => ['name' => '']], + ['name' => 'preference#set_default', 'url' => '/preference/default', 'verb' => 'POST'], + ['name' => 'preference#delete_default', 'url' => '/preference/default/{scope}/{name}', 'verb' => 'DELETE'], + ['name' => 'preference#get', 'url' => '/preference/{fileId}/{scope}/{name}', 'verb' => 'GET', 'defaults' => ['name' => '']], + ['name' => 'preference#set', 'url' => '/preference', 'verb' => 'POST'], + ['name' => 'preference#delete', 'url' => '/preference/{fileId}/{scope}/{name}', 'verb' => 'DELETE'], - // Preferences - ['name' => 'preference#get_default', 'url' => '/preference/default/{scope}/{name}', 'verb' => 'GET', 'defaults' => ['name' => '']], - ['name' => 'preference#set_default', 'url' => '/preference/default', 'verb' => 'POST'], - ['name' => 'preference#delete_default', 'url' => '/preference/default/{scope}/{name}', 'verb' => 'DELETE'], - ['name' => 'preference#get', 'url' => '/preference/{fileId}/{scope}/{name}', 'verb' => 'GET', 'defaults' => ['name' => '']], - ['name' => 'preference#set', 'url' => '/preference', 'verb' => 'POST'], - ['name' => 'preference#delete', 'url' => '/preference/{fileId}/{scope}/{name}', 'verb' => 'DELETE'], - // User Settings ['name' => 'settings#setPreference', 'url' => '/settings/set', 'verb' => 'POST'], ]]; - diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..99a38c0 --- /dev/null +++ b/composer.json @@ -0,0 +1,25 @@ +{ + "name": "nextcloud/epubreader", + "description": "EPUB/CBZ/PDF ebook reader", + "version": "1.4.8", + "type": "project", + "license": "AGPL-3.0-or-later", + "require-dev": { + "symfony/event-dispatcher": "^5.4.22", + "nextcloud/ocp": "^27.0.0", + "psalm/phar": "^5.12.0", + "nextcloud/coding-standard": "^1.1.1" + }, + "scripts": { + "lint": "find . -name \\*.php -not -path './vendor/*' -print0 | xargs -0 -n1 php -l", + "cs:check": "php-cs-fixer fix --dry-run --diff", + "cs:fix": "php-cs-fixer fix", + "psalm:check": "psalm.phar --threads=1 --no-cache --show-info=true", + "psalm:fix": "psalm.phar --no-cache --alter --issues=InvalidReturnType,InvalidNullableReturnType,MissingParamType,InvalidFalsableReturnType" + }, + "config": { + "platform": { + "php": "7.4" + } + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..5fa5a64 --- /dev/null +++ b/composer.lock @@ -0,0 +1,709 @@ +{ + "_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": "72e9bc76d92d0e26e0b3af7ed7ce6a68", + "packages": [], + "packages-dev": [ + { + "name": "nextcloud/coding-standard", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/nextcloud/coding-standard.git", + "reference": "55def702fb9a37a219511e1d8c6fe8e37164c1fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nextcloud/coding-standard/zipball/55def702fb9a37a219511e1d8c6fe8e37164c1fb", + "reference": "55def702fb9a37a219511e1d8c6fe8e37164c1fb", + "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.1.1" + }, + "time": "2023-06-01T12:05:01+00:00" + }, + { + "name": "nextcloud/ocp", + "version": "v27.0.0", + "source": { + "type": "git", + "url": "https://github.com/nextcloud-deps/ocp.git", + "reference": "c374aa2d4c3491812c19a53ce14063127daea08e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/c374aa2d4c3491812c19a53ce14063127daea08e", + "reference": "c374aa2d4c3491812c19a53ce14063127daea08e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ~8.0 || ~8.1", + "psr/clock": "^1.0", + "psr/container": "^2.0.2", + "psr/event-dispatcher": "^1.0", + "psr/log": "^1.1.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-stable27": "27.0.0-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "AGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Christoph Wurst", + "email": "christoph@winzerhof-wurst.at" + } + ], + "description": "Composer package containing Nextcloud's public API (classes, interfaces)", + "support": { + "issues": "https://github.com/nextcloud-deps/ocp/issues", + "source": "https://github.com/nextcloud-deps/ocp/tree/v27.0.0" + }, + "time": "2023-06-16T07:25:09+00:00" + }, + { + "name": "php-cs-fixer/shim", + "version": "v3.17.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/shim.git", + "reference": "f51b4aed90565c447136f1d015798f6f7c82490f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/shim/zipball/f51b4aed90565c447136f1d015798f6f7c82490f", + "reference": "f51b4aed90565c447136f1d015798f6f7c82490f", + "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.17.0" + }, + "time": "2023-05-22T20:00:38+00:00" + }, + { + "name": "psalm/phar", + "version": "5.12.0", + "source": { + "type": "git", + "url": "https://github.com/psalm/phar.git", + "reference": "e7f9306ec83c706b4dba451f6adfb865ce4688e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/psalm/phar/zipball/e7f9306ec83c706b4dba451f6adfb865ce4688e4", + "reference": "e7f9306ec83c706b4dba451f6adfb865ce4688e4", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "vimeo/psalm": "*" + }, + "bin": [ + "psalm.phar" + ], + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer-based Psalm Phar", + "support": { + "issues": "https://github.com/psalm/phar/issues", + "source": "https://github.com/psalm/phar/tree/5.12.0" + }, + "time": "2023-05-22T21:30:41+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.5.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:53:40+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v5.4.22", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "1df20e45d56da29a4b1d8259dd6e950acbf1b13f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1df20e45d56da29a4b1d8259dd6e950acbf1b13f", + "reference": "1df20e45d56da29a4b1d8259dd6e950acbf1b13f", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/event-dispatcher-contracts": "^2|^3", + "symfony/polyfill-php80": "^1.16" + }, + "conflict": { + "symfony/dependency-injection": "<4.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/http-foundation": "^4.4|^5.0|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^4.4|^5.0|^6.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.22" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-03-17T11:31:58+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v2.5.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/f98b54df6ad059855739db6fcbc2d36995283fe1", + "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:53:40+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "platform-overrides": { + "php": "7.4" + }, + "plugin-api-version": "2.3.0" +} diff --git a/js/ready.js b/js/ready.js index d14fdfe..511fa4e 100644 --- a/js/ready.js +++ b/js/ready.js @@ -1,4 +1,4 @@ -document.onreadystatechange = function () { +document.onreadystatechange = function () { if (document.readyState == "complete") { @@ -77,7 +77,7 @@ document.onreadystatechange = function () { return $.get(options.session.basePath + "bookmark/cursor/" + options.session.fileId); }; options.session.setCursor = function(value) { - return $.post(options.session.basePath + "bookmark/cursor", + return $.post(options.session.basePath + "bookmark/cursor", { "fileId": options.session.fileId, "value": JSON.stringify(value) @@ -103,7 +103,7 @@ document.onreadystatechange = function () { } } - // why is there no standard library function for this? + // why is there no standard library function for this? function getUrlParameter (param) { var pattern = new RegExp('[?&]'+param+'((=([^&]*))|(?=(&|$)))','i'); var m = window.location.search.match(pattern); @@ -113,9 +113,9 @@ document.onreadystatechange = function () { // start epub.js renderer function renderEpub(file, options) { - // some parameters... - EPUBJS.filePath = "vendor/epubjs/"; - EPUBJS.cssPath = "vendor/epubjs/css/"; + // some parameters... + EPUBJS.filePath = "public/epubjs/"; + EPUBJS.cssPath = "public/epubjs/css/"; EPUBJS.basePath = $('.session').data('basepath'); EPUBJS.staticPath = $('.session').data('staticpath'); @@ -136,16 +136,16 @@ document.onreadystatechange = function () { // start cbr.js renderer function renderCbr(file, options) { - CBRJS.filePath = "vendor/cbrjs/"; + CBRJS.filePath = "public/cbrjs/"; var reader = cbReader(file, options); } // start pdf.js renderer function renderPdf(file, options) { - PDFJS.filePath = "vendor/pdfjs/"; - PDFJS.imageResourcesPath = "vendor/pdfjs/css/images/"; - PDFJS.workerSrc = options.session.staticPath + 'vendor/pdfjs/lib/pdf.worker.js'; + PDFJS.filePath = "public/pdfjs/"; + PDFJS.imageResourcesPath = "public/pdfjs/css/images/"; + PDFJS.workerSrc = options.session.staticPath + 'public/pdfjs/lib/pdf.worker.js'; var reader = pdfReader(file, options); } diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php new file mode 100644 index 0000000..8810fbd --- /dev/null +++ b/lib/AppInfo/Application.php @@ -0,0 +1,41 @@ +getContainer(); + /** @var IRootFolder $rootFolder */ + $rootFolder = $container->get(IRootFolder::class); + /** @var IDBConnection $dbConnection */ + $dbConnection = $container->get(IDBConnection::class); + $hooks = new Hooks($rootFolder, $dbConnection); + $hooks->register(); + + /** @psalm-suppress DeprecatedMethod */ + Util::connectHook('\OCP\Config', 'js', 'OCA\Epubreader\Hooks', 'announce_settings'); + Util::addscript(self::APP_ID, 'plugin'); + } +} diff --git a/lib/Controller/BookmarkController.php b/lib/Controller/BookmarkController.php index 7d0a80e..c608f10 100644 --- a/lib/Controller/BookmarkController.php +++ b/lib/Controller/BookmarkController.php @@ -10,115 +10,106 @@ namespace OCA\Epubreader\Controller; -use OCP\IRequest; -use OCP\AppFramework\Controller; -use OCP\AppFramework\Http\DataResponse; - - use OCA\Epubreader\Service\BookmarkService; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\JSONResponse; +use OCP\IRequest; class BookmarkController extends Controller { - private $bookmarkService; + private BookmarkService $bookmarkService; /** * @param string $AppName * @param IRequest $request - * @param BookmarkService $bookmarkService + * @param BookmarkService $bookmarkService */ - public function __construct($AppName, - IRequest $request, - BookmarkService $bookmarkService ) { - - parent::__construct($AppName, $request); - $this->bookmarkService = $bookmarkService; - } - - /** - * @brief return bookmark - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @param int $fileId - * @param string $name - * - * @return array|\OCP\AppFramework\Http\JSONResponse - */ - public function get($fileId, $name, $type=null) { - return $this->bookmarkService->get($fileId, $name, $type); - } - - /** - * @brief write bookmark - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @param int $fileId - * @param string $name - * @param string $value - * - * @return array|\OCP\AppFramework\Http\JSONResponse - */ - public function set($fileId, $name, $value, $type=null, $content=null) { - return $this->bookmarkService->set($fileId, $name, $value, $type, $content); + public function __construct( + string $AppName, + IRequest $request, + BookmarkService $bookmarkService + ) { + parent::__construct($AppName, $request); + $this->bookmarkService = $bookmarkService; } + /** + * @brief return bookmark + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @param int $fileId + * @param ?string $name + * @param ?string $type + */ + public function get(int $fileId, ?string $name = null, ?string $type = null): JSONResponse { + return new JSONResponse($this->bookmarkService->get($fileId, $name, $type)); + } /** - * @brief return cursor for $fileId - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @param int $fileId - * - * @return array|\OCP\AppFramework\Http\JSONResponse + * @brief write bookmark + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @param int $fileId + * @param string $name + * @param string $value + * @param ?string $type + * @param ?string $content */ - public function getCursor($fileId) { - return $this->bookmarkService->getCursor($fileId); - } + public function set(int $fileId, string $name, string $value, ?string $type = null, ?string $content = null): JSONResponse { + return new JSONResponse($this->bookmarkService->set($fileId, $name, $value, $type, $content)); + } /** - * @brief write cursor for $fileId - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @param int $fileId - * @param string $value - * - * @return array|\OCP\AppFramework\Http\JSONResponse + * @brief return cursor for $fileId + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @param int $fileId */ - public function setCursor($fileId, $value) { - return $this->bookmarkService->setCursor($fileId, $value); - } + public function getCursor(int $fileId): JSONResponse { + return new JSONResponse($this->bookmarkService->getCursor($fileId)); + } - /** - * @brief delete bookmark - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @param int $fileId - * @param string name - * - */ - public function delete($fileId, $name) { - return $this->bookmarkService->delete($fileId, $name); - } + /** + * @brief write cursor for $fileId + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @param int $fileId + * @param string $value + */ + public function setCursor(int $fileId, string $value): JSONResponse { + return new JSONResponse($this->bookmarkService->setCursor($fileId, $value)); + } - /** - * @brief delete cursor - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @param int $fileId - * - */ - public function deleteCursor($fileId) { - return $this->bookmarkService->deleteCursor($fileId); - } + /** + * @brief delete bookmark + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @param int $fileId + * @param string name + */ + public function delete(int $fileId, string $name): void { + $this->bookmarkService->delete($fileId, $name); + } + + /** + * @brief delete cursor + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @param int $fileId + */ + public function deleteCursor(int $fileId): void { + $this->bookmarkService->deleteCursor($fileId); + } } diff --git a/lib/Controller/MetadataController.php b/lib/Controller/MetadataController.php deleted file mode 100644 index d021ffb..0000000 --- a/lib/Controller/MetadataController.php +++ /dev/null @@ -1,80 +0,0 @@ -metadataService = $metadataService; - } - - - /** - * @brief write metadata - * - * @NoAdminRequired - * - * @param int $fileId - * @param string $value - * - * @return array|\OCP\AppFramework\Http\JSONResponse - */ - public function setAll($fileId, $value) { - return $this->metadataService->setAll($fileId, $value); - } - - /** - * @brief return metadata item - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @param int $fileId - * @param string $name - * - * @return array|\OCP\AppFramework\Http\JSONResponse - */ - public function get($fileId, $name) { - return $this->metadataService->get($fileId, $name); - } - - /** - * @brief write metadata item - * - * @NoAdminRequired - * - * @param int $fileId - * @param string $name - * @param string $value - * - * @return array|\OCP\AppFramework\Http\JSONResponse - */ - public function set($fileId, $name, $value) { - return $this->metadataService->set($fileId, $name, $value); - } - -} diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 126fe68..99e6bdd 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -10,168 +10,167 @@ namespace OCA\Epubreader\Controller; +use OCA\Epubreader\Service\BookmarkService; +use OCA\Epubreader\Service\PreferenceService; use OCP\AppFramework\Controller; -use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Http\ContentSecurityPolicy; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\Files\FileInfo; +use OCP\Files\Folder; +use OCP\Files\InvalidPathException; +use OCP\Files\IRootFolder; +use OCP\Files\NotFoundException; use OCP\IRequest; use OCP\IURLGenerator; -use OCP\Files\IRootFolder; use OCP\Share\IManager; -use OCP\Files\FileInfo; -use OCP\Files\NotFoundException; - -use OCA\Epubreader\Service\BookmarkService; -use OCA\Epubreader\Service\MetadataService; -use OCA\Epubreader\Service\PreferenceService; class PageController extends Controller { - /** @var IURLGenerator */ - private $urlGenerator; - /** @var IRootFolder */ - private $rootFolder; - private $shareManager; - private $userId; - private $bookmarkService; - private $metadataService; - private $preferenceService; + private IURLGenerator $urlGenerator; + private IRootFolder $rootFolder; + private IManager $shareManager; + private string $userId; + private BookmarkService $bookmarkService; + private PreferenceService $preferenceService; - /** - * @param string $AppName - * @param IRequest $request - * @param IURLGenerator $urlGenerator - * @param IRootFolder $rootFolder - * @param IManager $shareManager - * @param string $UserId - * @param BookmarkService $bookmarkService - * @param PreferenceService $preferenceService - * @param MetadataService $metadataService - */ - public function __construct( - $AppName, - IRequest $request, - IURLGenerator $urlGenerator, - IRootFolder $rootFolder, - IManager $shareManager, - $UserId, - BookmarkService $bookmarkService, - PreferenceService $preferenceService, - MetadataService $metadataService) { - parent::__construct($AppName, $request); - $this->urlGenerator = $urlGenerator; - $this->rootFolder = $rootFolder; - $this->shareManager = $shareManager; - $this->userId = $UserId; - $this->bookmarkService = $bookmarkService; - $this->metadataService = $metadataService; - $this->preferenceService = $preferenceService; - } + /** + * @param string $AppName + * @param IRequest $request + * @param IURLGenerator $urlGenerator + * @param IRootFolder $rootFolder + * @param IManager $shareManager + * @param string $UserId + * @param BookmarkService $bookmarkService + * @param PreferenceService $preferenceService + */ + public function __construct( + string $AppName, + IRequest $request, + IURLGenerator $urlGenerator, + IRootFolder $rootFolder, + IManager $shareManager, + string $UserId, + BookmarkService $bookmarkService, + PreferenceService $preferenceService, + ) { + parent::__construct($AppName, $request); + $this->urlGenerator = $urlGenerator; + $this->rootFolder = $rootFolder; + $this->shareManager = $shareManager; + $this->userId = $UserId; + $this->bookmarkService = $bookmarkService; + $this->preferenceService = $preferenceService; + } - /** - * @PublicPage - * @NoCSRFRequired - * - * @return TemplateResponse - */ - public function showReader() { - $templates= [ - 'application/epub+zip' => 'epubreader', - 'application/x-cbr' => 'cbreader', - 'application/pdf' => 'pdfreader' - ]; + /** + * @PublicPage + * @NoCSRFRequired + */ + public function showReader(): TemplateResponse { + $templates = [ + 'application/epub+zip' => 'epubreader', + 'application/x-cbr' => 'cbreader', + 'application/pdf' => 'pdfreader' + ]; - /** - * $fileInfo = [ - * fileId => null, - * fileName => null, - * fileType => null - * ]; - */ - $fileInfo = $this->getFileInfo($this->request->get['file']); - $fileId = $fileInfo['fileId']; - $type = $this->request->get["type"]; - $scope = $template = $templates[$type]; + /** + * @var array{ + * fileId: int, + * fileName: string, + * fileType: string + * } $fileInfo + */ + $fileInfo = $this->getFileInfo((string) $this->request->getParam('file')); + $fileId = $fileInfo['fileId']; + $type = (string) $this->request->getParam('type'); + $scope = $template = $templates[$type]; - $params = [ - 'urlGenerator' => $this->urlGenerator, - 'downloadLink' => $this->request->get['file'], - 'scope' => $scope, - 'fileId' => $fileInfo['fileId'], - 'fileName' => $fileInfo['fileName'], - 'fileType' => $fileInfo['fileType'], - 'cursor' => $this->toJson($this->bookmarkService->getCursor($fileId)), - 'defaults' => $this->toJson($this->preferenceService->getDefault($scope)), - 'preferences' => $this->toJson($this->preferenceService->get($scope, $fileId)), - 'defaults' => $this->toJson($this->preferenceService->getDefault($scope)), - 'metadata' => $this->toJson($this->metadataService->get($fileId)), - 'annotations' => $this->toJson($this->bookmarkService->get($fileId)) - ]; + $params = [ + 'urlGenerator' => $this->urlGenerator, + 'downloadLink' => $this->request->getParam('file'), + 'scope' => $scope, + 'fileId' => $fileInfo['fileId'], + 'fileName' => $fileInfo['fileName'], + 'fileType' => $fileInfo['fileType'], + 'cursor' => $this->toJson($this->bookmarkService->getCursor($fileId)), + 'defaults' => $this->toJson($this->preferenceService->getDefault($scope)), + 'preferences' => $this->toJson($this->preferenceService->get($scope, $fileId)), + 'metadata' => $this->toJson([]), + 'annotations' => $this->toJson($this->bookmarkService->get($fileId)) + ]; - $policy = new ContentSecurityPolicy(); + $policy = new ContentSecurityPolicy(); $policy->addAllowedStyleDomain('\'self\''); $policy->addAllowedStyleDomain('blob:'); $policy->addAllowedScriptDomain('\'self\''); $policy->addAllowedFrameDomain('\'self\''); - $policy->addAllowedChildSrcDomain('\'self\''); $policy->addAllowedFontDomain('\'self\''); $policy->addAllowedFontDomain('data:'); $policy->addAllowedFontDomain('blob:'); $policy->addAllowedImageDomain('blob:'); - $response = new TemplateResponse($this->appName, $template, $params, 'blank'); + $response = new TemplateResponse($this->appName, $template, $params, 'blank'); $response->setContentSecurityPolicy($policy); - return $response; - } + return $response; + } - /** - * @brief sharing-aware file info retriever - * - * Work around the differences between normal and shared file access - * (this should be abstracted away in OC/NC IMnsHO) - * - * @param string $path path-fragment from url - * @return array - * @throws NotFoundException - */ - private function getFileInfo($path) { - $count = 0; - $shareToken = preg_replace("/(?:\/index\.php)?\/s\/([A-Za-z0-9]{15,32})\/download.*/", "$1", $path, 1,$count); + /** + * @brief sharing-aware file info retriever + * + * Work around the differences between normal and shared file access + * (this should be abstracted away in OC/NC IMnsHO) + * + * @param string $path path-fragment from url + * + * @throws NotFoundException|InvalidPathException + */ + private function getFileInfo(string $path): array { + $count = 0; + $shareToken = preg_replace("/(?:\/index\.php)?\/s\/([A-Za-z0-9]{15,32})\/download.*/", "$1", $path, 1, $count); - if ($count === 1) { + if ($count === 1) { + /* shared file or directory */ + $node = $this->shareManager->getShareByToken($shareToken)->getNode(); + $type = $node->getType(); - /* shared file or directory */ - $node = $this->shareManager->getShareByToken($shareToken)->getNode(); - $type = $node->getType(); + /* shared directory, need file path to continue, */ + if ($type == FileInfo::TYPE_FOLDER && $node instanceof Folder) { + $query = []; + parse_str(parse_url($path, PHP_URL_QUERY), $query); + if (isset($query['path']) && is_string($query['path'])) { + $node = $node->get($query['path']); + } elseif (isset($query['files']) && is_string($query['files'])) { + $node = $node->get($query['files']); + } else { + throw new NotFoundException('Shared file path or name not set'); + } + } + $filePath = $node->getPath(); + $fileId = $node->getId(); + } else { + $filePath = $path; + $fileId = $this->rootFolder->getUserFolder($this->userId) + ->get(preg_replace("/.*\/remote.php\/webdav(.*)/", "$1", rawurldecode((string) $this->request->getParam('file')))) + ->getId(); + } - /* shared directory, need file path to continue, */ - if ($type == \OCP\Files\FileInfo::TYPE_FOLDER) { - $query = []; - parse_str(parse_url($path, PHP_URL_QUERY), $query); - if (isset($query['path']) && isset($query['files'])) { - $node = $node->get($query['path'])->get($query['files']); - } else { - throw new NotFoundException('Shared file path or name not set'); - } - } - $filePath = $node->getPath(); - $fileId = $node->getId(); - } else { - $filePath = $path; - $fileId = $this->rootFolder->getUserFolder($this->userId) - ->get(preg_replace("/.*\/remote.php\/webdav(.*)/", "$1", rawurldecode($this->request->get['file']))) - ->getFileInfo() - ->getId(); - } + $pathInfo = pathInfo($filePath); + if (!is_array($pathInfo)) { + throw new InvalidPathException("Can not get info for $filePath"); + } - return [ - 'fileName' => pathInfo($filePath, PATHINFO_FILENAME), - 'fileType' => strtolower(pathInfo($filePath, PATHINFO_EXTENSION)), - 'fileId' => $fileId - ]; - } + return [ + 'fileName' => $pathInfo['filename'], + 'fileType' => strtolower($pathInfo['extension'] ?? ''), + 'fileId' => $fileId + ]; + } - private function toJson($value) { - return htmlspecialchars(json_encode($value), ENT_QUOTES, 'UTF-8'); - } + /** + * @param mixed $value + */ + private function toJson($value): string { + return htmlspecialchars(json_encode($value), ENT_QUOTES, 'UTF-8'); + } } diff --git a/lib/Controller/PreferenceController.php b/lib/Controller/PreferenceController.php index d408247..2da664d 100644 --- a/lib/Controller/PreferenceController.php +++ b/lib/Controller/PreferenceController.php @@ -10,119 +10,104 @@ namespace OCA\Epubreader\Controller; -use OCP\IRequest; -use OCP\IURLGenerator; -use OCP\AppFramework\Http; -use OCP\AppFramework\Controller; - use OCA\Epubreader\Service\PreferenceService; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\JSONResponse; +use OCP\IRequest; class PreferenceController extends Controller { - private $urlGenerator; - private $preferenceService; - - /** - * @param string $AppName - * @param IRequest $request - * @param IURLGenerator $urlGenerator - * @param PreferenceService $preferenceService - */ - public function __construct($AppName, - IRequest $request, - IURLGenerator $urlGenerator, - PreferenceService $preferenceService ) { + private PreferenceService $preferenceService; + /** + * @param string $AppName + * @param IRequest $request + * @param PreferenceService $preferenceService + */ + public function __construct( + string $AppName, + IRequest $request, + PreferenceService $preferenceService + ) { parent::__construct($AppName, $request); - $this->urlGenerator = $urlGenerator; - $this->preferenceService = $preferenceService; - } + $this->preferenceService = $preferenceService; + } /** - * @brief return preference for $fileId - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @param string $scope - * @param int $fileId - * @param string $name if null, return all preferences for $scope + $fileId - * - * @return array|\OCP\AppFramework\Http\JSONResponse + * @brief return preference for $fileId + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @param string $scope + * @param int $fileId + * @param ?string $name if null, return all preferences for $scope + $fileId */ - public function get($scope, $fileId, $name) { - return $this->preferenceService->get($scope, $fileId, $name); - } + public function get(string $scope, int $fileId, ?string $name = null): JSONResponse { + return new JSONResponse($this->preferenceService->get($scope, $fileId, $name)); + } /** - * @brief write preference for $fileId - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @param string $scope - * @param int $fileId - * @param string $name - * @param string $value - * - * @return array|\OCP\AppFramework\Http\JSONResponse + * @brief write preference for $fileId + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @param string $scope + * @param int $fileId + * @param string $name + * @param string $value */ - public function set($scope, $fileId, $name, $value) { - return $this->preferenceService->set($scope, $fileId, $name, $value); + public function set(string $scope, int $fileId, string $name, string $value): JSONResponse { + return new JSONResponse($this->preferenceService->set($scope, $fileId, $name, $value)); } /** - * @brief return default preference - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @param string $scope - * @param string $name if null, return all default preferences for scope - * - * @return array|\OCP\AppFramework\Http\JSONResponse + * @brief return default preference + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @param string $scope + * @param string $name if null, return all default preferences for scope */ - public function getDefault($scope, $name) { - return $this->preferenceService->getDefault($scope, $name); - } + public function getDefault(string $scope, string $name): JSONResponse { + return new JSONResponse($this->preferenceService->getDefault($scope, $name)); + } /** - * @brief write default preference - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @param string $scope - * @param string $name - * @param string $value - * - * @return array|\OCP\AppFramework\Http\JSONResponse + * @brief write default preference + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @param string $scope + * @param string $name + * @param string $value */ - public function setDefault($scope, $name, $value) { - return $this->preferenceService->setDefault($scope, $name, $value); - } + public function setDefault(string $scope, string $name, string $value): JSONResponse { + return new JSONResponse($this->preferenceService->setDefault($scope, $name, $value)); + } - /** - * @brief delete preference - * - * @param string $scope - * @param int $fileId - * @param string $name - * - */ - public function delete($scope, $fileId, $name) { - return $this->preferenceService->delete($scope, $fileId, $name); - } + /** + * @brief delete preference + * + * @param string $scope + * @param int $fileId + * @param string $name + */ + public function delete(string $scope, int $fileId, string $name): void { + $this->preferenceService->delete($scope, $fileId, $name); + } - /** - * @brief delete default preference - * - * @param $scope - * @param $name - * - */ - public function deleteDefault($scope, $name) { - return $this->preferenceService->deleteDefault($scope, $name); - } + /** + * @brief delete default preference + * + * @param string $scope + * @param string $name + */ + public function deleteDefault(string $scope, string $name): void { + $this->preferenceService->deleteDefault($scope, $name); + } } diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index 7b26a34..a3c8421 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -11,59 +11,52 @@ */ namespace OCA\Epubreader\Controller; -use OCP\IRequest; -use OCP\IURLGenerator; -use OCP\AppFramework\Http; + +use OCA\Epubreader\AppInfo\Application; use OCP\AppFramework\Controller; -use OCA\Epubreader\Service\PreferenceService; -use OCA\Epubreader\Config; use OCP\AppFramework\Http\JSONResponse; +use OCP\IConfig; +use OCP\IL10N; +use OCP\IRequest; class SettingsController extends Controller { - - private $urlGenerator; - private $preferenceService; - /** - * @param string $AppName - * @param IRequest $request - * @param IURLGenerator $urlGenerator - * @param PreferenceService $preferenceService - */ - public function __construct($AppName, - IRequest $request, - IURLGenerator $urlGenerator, - PreferenceService $preferenceService ) { + private string $userId; + private IL10N $l10n; + private IConfig $configManager; + + public function __construct( + string $appName, + IRequest $request, + string $userId, + IL10N $l10n, + IConfig $configManager + ) { + parent::__construct($appName, $request); + $this->userId = $userId; + $this->l10n = $l10n; + $this->configManager = $configManager; + } - parent::__construct($AppName, $request); - $this->urlGenerator = $urlGenerator; - $this->preferenceService = $preferenceService; - } - /** - * @brief set preference for file type association - * - * @NoAdminRequired - * - * @param int $EpubEnable - * @param int $EpubEnable - * @param int $CbxEnable - * - * @return array|\OCP\AppFramework\Http\JSONResponse + * @brief set preference for file type association + * + * @NoAdminRequired + * + * @param string $EpubEnable + * @param string $PdfEnable + * @param string $CbxEnable */ - public function setPreference(string $EpubEnable, string $PdfEnable, string $CbxEnable) { + public function setPreference(string $EpubEnable, string $PdfEnable, string $CbxEnable): JSONResponse { + $this->configManager->setUserValue($this->userId, Application::APP_ID, 'epub_enable', $EpubEnable); + $this->configManager->setUserValue($this->userId, Application::APP_ID, 'pdf_enable', $PdfEnable); + $this->configManager->setUserValue($this->userId, Application::APP_ID, 'cbx_enable', $CbxEnable); - $l = \OC::$server->getL10N('epubreader'); - - Config::set('epub_enable', $EpubEnable); - Config::set('pdf_enable', $PdfEnable); - Config::set('cbx_enable', $CbxEnable); - - $response = array( - 'data' => array('message'=> $l->t('Settings updated successfully.')), - 'status' => 'success' - ); + $response = [ + 'data' => ['message' => $this->l10n->t('Settings updated successfully.')], + 'status' => 'success' + ]; return new JSONResponse($response); } -} \ No newline at end of file +} diff --git a/lib/Db/Bookmark.php b/lib/Db/Bookmark.php index e3748e9..76ac1d0 100644 --- a/lib/Db/Bookmark.php +++ b/lib/Db/Bookmark.php @@ -10,39 +10,89 @@ namespace OCA\Epubreader\Db; -use OCP\AppFramework\Db\Entity; - class Bookmark extends ReaderEntity implements \JsonSerializable { - protected $userId; // user - protected $fileId; // book (identified by fileId) for which this mark is valid - protected $type; // type, defaults to "bookmark" - protected $name; // name, defaults to $location - protected $value; // bookmark value (format-specific, eg. page number for PDF, CFI for epub, etc) - protected $content; // bookmark content (annotations etc), can be empty - protected $lastModified; // modification timestamp + protected string $userId; // user + protected int $fileId; // book (identified by fileId) for which this mark is valid + protected string $type; // type, defaults to "bookmark" + protected string $name; // name, defaults to $location + protected string $value; // bookmark value (format-specific, eg. page number for PDF, CFI for epub, etc) + protected string $content; // bookmark content (annotations etc), can be empty - public function jsonSerialize() { - return [ - 'id' => $this->getId(), - 'userId' => $this->getUserId(), - 'fileId' => $this->getFileId(), - 'type' => $this->getType(), - 'name' => $this->getName(), - 'value' => static::conditional_json_decode($this->getValue()), - 'content' => static::conditional_json_decode($this->getContent()), - 'lastModified' => $this->getLastModified() - ]; - } + public function jsonSerialize(): array { + return [ + 'id' => $this->getId(), + 'userId' => $this->getUserId(), + 'fileId' => $this->getFileId(), + 'type' => $this->getType(), + 'name' => $this->getName(), + 'value' => $this->conditional_json_decode($this->getValue()), + 'content' => $this->conditional_json_decode($this->getContent()), + 'lastModified' => $this->getLastModified() + ]; + } - public function toService() { - return [ - 'name' => $this->getName(), - 'type' => $this->getType(), - 'value' => $this->conditional_json_decode($this->getValue()), - 'content' => $this->conditional_json_decode($this->getContent()), - 'lastModified' => $this->getLastModified(), - ]; - } + public function toService(): array { + return [ + 'name' => $this->getName(), + 'type' => $this->getType(), + 'value' => $this->conditional_json_decode($this->getValue()), + 'content' => $this->conditional_json_decode($this->getContent()), + 'lastModified' => $this->getLastModified(), + ]; + } + + public function getUserId(): string { + return $this->userId; + } + + public function setUserId(string $userId): void { + $this->userId = $userId; + $this->markFieldUpdated('userId'); + } + + public function getFileId(): int { + return $this->fileId; + } + + public function setFileId(int $fileId): void { + $this->fileId = $fileId; + $this->markFieldUpdated('fileId'); + } + + public function getType(): string { + return $this->type; + } + + public function setType(string $type): void { + $this->type = $type; + $this->markFieldUpdated('type'); + } + + public function getName(): string { + return $this->name; + } + + public function setName(string $name): void { + $this->name = $name; + $this->markFieldUpdated('name'); + } + + public function getValue(): string { + return $this->value; + } + + public function setValue(string $value): void { + $this->value = $value; + $this->markFieldUpdated('value'); + } + + public function getContent(): string { + return $this->content; + } + + public function setContent(string $content): void { + $this->content = $content; + $this->markFieldUpdated('content'); + } } - diff --git a/lib/Db/BookmarkMapper.php b/lib/Db/BookmarkMapper.php index 6ed45ee..4f76308 100644 --- a/lib/Db/BookmarkMapper.php +++ b/lib/Db/BookmarkMapper.php @@ -10,115 +10,93 @@ namespace OCA\Epubreader\Db; - -use OCP\IDBConnection; - use OCA\Epubreader\Utility\Time; +use OCP\IDBConnection; class BookmarkMapper extends ReaderMapper { - private $userId; + private string $userId; - /** - * @param IDbConnection $db - * @param $UserId - * @param Time $time - */ - public function __construct(IDBConnection $db, $UserId, Time $time) { - parent::__construct($db, 'reader_bookmarks', Bookmark::class, $time); - /** @var int $UserId */ - $this->userId = $UserId; - } + /** + * @param IDbConnection $db + * @param string $UserId + * @param Time $time + */ + public function __construct(IDBConnection $db, string $UserId, Time $time) { + parent::__construct($db, 'reader_bookmarks', Bookmark::class, $time); + $this->userId = $UserId; + } - /** - * @brief get bookmarks for $fileId+$userId(+$name) - * @param $fileId - * @param string $name - * @return array - */ - public function get($fileId, $name, $type = null) { - $query = $this->db->getQueryBuilder(); - $query->select('*') - ->from($this->getTableName()) - ->where($query->expr()->eq('file_id', $query->createNamedParameter($fileId))) - ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($this->userId))); + /** + * @brief get bookmarks for $fileId+$userId(+$name) + * @param int $fileId + * @param ?string $name + * @param ?string $type + * + * @return ReaderEntity[] + */ + public function get(int $fileId, ?string $name = null, ?string $type = null): array { + $query = $this->db->getQueryBuilder(); + $query->select('*') + ->from($this->getTableName()) + ->where($query->expr()->eq('file_id', $query->createNamedParameter($fileId))) + ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($this->userId))); - if ($type !== null) { - $query->andWhere($query->expr()->eq('type', $query->createNamedParameter($type))); - } + if ($type !== null) { + $query->andWhere($query->expr()->eq('type', $query->createNamedParameter($type))); + } - if ($name !== null) { - $query->andWhere($query->expr()->eq('name', $query->createNamedParameter($name))); - } + if ($name !== null) { + $query->andWhere($query->expr()->eq('name', $query->createNamedParameter($name))); + } - return $this->findEntities($query); - } + return $this->findEntities($query); + } - /** - * @brief write bookmark to database - * - * @param int $fileId - * @param string $name - * @param string $value - * - * @return Bookmark the newly created or updated bookmark - */ - public function set($fileId, $name, $value, $type, $content=null) { + /** + * @brief write bookmark to database + * + * @param int $fileId + * @param string $name + * @param string $value + * @param ?string $type + * @param ?string $content + * + * @return ReaderEntity the newly created or updated bookmark + */ + public function set(int $fileId, string $name, string $value, ?string $type = null, ?string $content = null): ReaderEntity { + $result = $this->get($fileId, $name); - $result = $this->get($fileId, $name); + if(empty($result)) { + // anonymous bookmarks are named after their contents + if (empty($name)) { + $name = $value; + } - if(empty($result)) { + // default type is "bookmark" + if (null === $type) { + $type = "bookmark"; + } - // anonymous bookmarks are named after their contents - if (null === $name) { - $name = $value; - } + $bookmark = new Bookmark(); + $bookmark->setFileId($fileId); + $bookmark->setUserId($this->userId); + $bookmark->setType($type); + $bookmark->setName($name); + $bookmark->setValue($value); + $bookmark->setContent($content ?? ''); - // default type is "bookmark" - if (null === $type) { - $type = "bookmark"; - } + $this->insert($bookmark); + } elseif ($result[0] instanceof Bookmark) { + $bookmark = $result[0]; + $bookmark->setValue($value); + $bookmark->setContent($content ?? ''); - $bookmark = new Bookmark(); - $bookmark->setFileId($fileId); - $bookmark->setUserId($this->userId); - $bookmark->setType($type); - $bookmark->setName($name); - $bookmark->setValue($value); - $bookmark->setContent($content); + $this->update($bookmark); + } else { + $bookmark = new Bookmark(); + } - $this->insert($bookmark); - } else { - $bookmark = $result[0]; - $bookmark->setValue($value); - $bookmark->setContent($content); - - $this->update($bookmark); - } - - return $bookmark; - } - - /* currently not used */ - public function deleteForFileId($fileId) { - $sql = "SELECT * FROM `*PREFIX*reader_bookmarks` WHERE file_id=?"; - $args = [ $fileId ]; - array_map( - function($entity) { - $this->delete($entity); - }, $this->findEntities($sql, $args) - ); - } - - /* currently not used */ - public function deleteForUserId($userId) { - $sql = "SELECT * FROM `*PREFIX*reader_bookmarks` WHERE user_id=?"; - $args = [ $userId ]; - array_map( - function($entity) { - $this->delete($entity); - }, $this->findEntities($sql, $args) - ); - } + return $bookmark; + } } - diff --git a/lib/Db/Preference.php b/lib/Db/Preference.php index 3e12fa0..0f11de3 100644 --- a/lib/Db/Preference.php +++ b/lib/Db/Preference.php @@ -10,33 +10,74 @@ namespace OCA\Epubreader\Db; -use OCP\AppFramework\Db\Entity; - class Preference extends ReaderEntity implements \JsonSerializable { - protected $userId; // user for whom this preference is valid - protected $scope; // scope (default or specific renderer) - protected $fileId; // file for which this preference is set - protected $name; // preference name - protected $value; // preference value - protected $lastModified; // modification timestamp + protected string $userId; // user for whom this preference is valid + protected string $scope; // scope (default or specific renderer) + protected int $fileId; // file for which this preference is set + protected string $name; // preference name + protected string $value; // preference value - public function jsonSerialize() { - return [ - 'id' => $this->getId(), - 'scope' => $this->getScope(), - 'fileId' => $this->getFileId(), - 'name' => $this->getName(), - 'value' => $this->conditional_json_decode($this->getValue()), - 'lastModified' => $this->getLastModified(), - ]; - } + public function jsonSerialize(): array { + return [ + 'id' => $this->getId(), + 'scope' => $this->getScope(), + 'fileId' => $this->getFileId(), + 'name' => $this->getName(), + 'value' => $this->conditional_json_decode($this->getValue()), + 'lastModified' => $this->getLastModified(), + ]; + } - public function toService() { - return [ - 'name' => $this->getName(), - 'value' => $this->conditional_json_decode($this->getValue()), - ]; - } + public function toService(): array { + return [ + 'name' => $this->getName(), + 'value' => $this->conditional_json_decode($this->getValue()), + ]; + } + + public function getUserId(): string { + return $this->userId; + } + + public function setUserId(string $userId): void { + $this->userId = $userId; + $this->markFieldUpdated('userId'); + } + + public function getScope(): string { + return $this->scope; + } + + public function setScope(string $scope): void { + $this->scope = $scope; + $this->markFieldUpdated('scope'); + } + + public function getFileId(): int { + return $this->fileId; + } + + public function setFileId(int $fileId): void { + $this->fileId = $fileId; + $this->markFieldUpdated('fileId'); + } + + public function getName(): string { + return $this->name; + } + + public function setName(string $name): void { + $this->name = $name; + $this->markFieldUpdated('name'); + } + + public function getValue(): string { + return $this->value; + } + + public function setValue(string $value): void { + $this->value = $value; + $this->markFieldUpdated('value'); + } } - diff --git a/lib/Db/PreferenceMapper.php b/lib/Db/PreferenceMapper.php index e4db648..07e8abe 100644 --- a/lib/Db/PreferenceMapper.php +++ b/lib/Db/PreferenceMapper.php @@ -10,93 +10,73 @@ namespace OCA\Epubreader\Db; -use OCP\DB\QueryBuilder\IQueryBuilder; use OCA\Epubreader\Utility\Time; use OCP\IDBConnection; class PreferenceMapper extends ReaderMapper { - public function __construct(IDBConnection $db, $UserId, Time $time) { - parent::__construct($db, 'reader_prefs', Preference::class, $time); - $this->userId = $UserId; - } + private string $userId; - /** - * @brief get preferences for $scope+$fileId+$userId(+$name) - * - * @param string $scope - * @param int $fileId - * @param string $name - * @return array - */ - public function get($scope, $fileId, $name=null) { - $query = $this->db->getQueryBuilder(); - $query->select('*') - ->from($this->getTableName()) - ->where($query->expr()->eq('scope', $query->createNamedParameter($scope))) - ->andWhere($query->expr()->eq('file_id', $query->createNamedParameter($fileId))) - ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($this->userId))); + public function __construct(IDBConnection $db, string $UserId, Time $time) { + parent::__construct($db, 'reader_prefs', Preference::class, $time); + $this->userId = $UserId; + } - if (!empty($name)) { - $query->andWhere($query->expr()->eq('name', $query->createNamedParameter($name))); - } + /** + * @brief get preferences for $scope+$fileId+$userId(+$name) + * + * @param string $scope + * @param int $fileId + * @param ?string $name + * + * @return ReaderEntity[] + */ + public function get(string $scope, int $fileId, ?string $name = null): array { + $query = $this->db->getQueryBuilder(); + $query->select('*') + ->from($this->getTableName()) + ->where($query->expr()->eq('scope', $query->createNamedParameter($scope))) + ->andWhere($query->expr()->eq('file_id', $query->createNamedParameter($fileId))) + ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($this->userId))); - return $this->findEntities($query); - } + if (!empty($name)) { + $query->andWhere($query->expr()->eq('name', $query->createNamedParameter($name))); + } - /** - * @brief write preference to database - * - * @param string $scope - * @param int $fileId - * @param string $name - * @param string $value - * - * @return Preference the newly created or updated preference - */ - public function set($scope, $fileId, $name, $value) { + return $this->findEntities($query); + } - $result = $this->get($scope, $fileId, $name); + /** + * @brief write preference to database + * + * @param string $scope + * @param int $fileId + * @param string $name + * @param string $value + * + * @return ReaderEntity the newly created or updated preference + */ + public function set(string $scope, int $fileId, string $name, string $value): ReaderEntity { + $result = $this->get($scope, $fileId, $name); - if(empty($result)) { + if(empty($result)) { + $preference = new Preference(); + $preference->setScope($scope); + $preference->setFileId($fileId); + $preference->setUserId($this->userId); + $preference->setName($name); + $preference->setValue($value); - $preference = new Preference(); - $preference->setScope($scope); - $preference->setFileId($fileId); - $preference->setUserId($this->userId); - $preference->setName($name); - $preference->setValue($value); + $this->insert($preference); + } elseif ($result[0] instanceof Preference) { + $preference = $result[0]; + $preference->setValue($value); - $this->insert($preference); - } else { - $preference = $result[0]; - $preference->setValue($value); + $this->update($preference); + } else { + $preference = new Preference(); + } - $this->update($preference); - } - - return $preference; - } - - /* currently not used*/ - public function deleteForFileId($fileId) { - $sql = "SELECT * FROM `*PREFIX*reader_prefs` WHERE file_id=?"; - $args = [ $fileId ]; - array_map( - function($entity) { - $this->delete($entity); - }, $this->findEntities($sql, $args) - ); - } - - /* currently not used*/ - public function deleteForUserId($userId) { - $sql = "SELECT * FROM `*PREFIX*reader_prefs` WHERE user_id=?"; - $args = [ $userId ]; - array_map( - function($entity) { - $this->delete($entity); - }, $this->findEntities($sql, $args) - ); - } + return $preference; + } } diff --git a/lib/Db/ReaderEntity.php b/lib/Db/ReaderEntity.php index 58cb907..66eb48a 100644 --- a/lib/Db/ReaderEntity.php +++ b/lib/Db/ReaderEntity.php @@ -12,28 +12,44 @@ namespace OCA\Epubreader\Db; use OCP\AppFramework\Db\Entity; -class ReaderEntity extends Entity { +/** + * @psalm-type SerializedEntity = array + */ +abstract class ReaderEntity extends Entity { - /* returns decoded json if input is json, otherwise returns input */ - public static function conditional_json_decode($el) { - $result = json_decode($el); - if (json_last_error() === JSON_ERROR_NONE) { - return $result; - } else { - return $el; - } - } + protected int $lastModified; // modification timestamp -/* - public function toService() { - return [ - 'name' => $this->getName(), - 'type' => $this->getType(), - 'value' => $this->conditional_json_decode($this->getValue()), - 'content' => $this->conditional_json_decode($this->getContent()), - 'lastModified' => $this->getLastModified(), - ]; - } -*/ + /** + * returns decoded json if input is json, otherwise returns input + * + * @return string|array + */ + public function conditional_json_decode(string $el): mixed { + /** @var array $result */ + $result = json_decode($el); + if (json_last_error() === JSON_ERROR_NONE) { + return $result; + } else { + return $el; + } + } + + public function getLastModified(): int { + return $this->lastModified; + } + + public function setLastModified(int $lastModified): void { + $this->lastModified = $lastModified; + $this->markFieldUpdated('lastModified'); + } + + /** + * @psalm-return SerializedEntity + */ + abstract public function toService(): array; + + /** + * @psalm-return SerializedEntity + */ + abstract public function jsonSerialize(): array; } - diff --git a/lib/Db/ReaderMapper.php b/lib/Db/ReaderMapper.php index 50969a6..ce6b9be 100644 --- a/lib/Db/ReaderMapper.php +++ b/lib/Db/ReaderMapper.php @@ -10,31 +10,36 @@ namespace OCA\Epubreader\Db; -use OCP\IDBConnection; -use OCP\AppFramework\Db\QBMapper; -use OCP\AppFramework\Db\Entity; - use OCA\Epubreader\Utility\Time; +use OCP\AppFramework\Db\Entity; +use OCP\AppFramework\Db\QBMapper; +use OCP\IDBConnection; +/** + * @template-extends QBMapper + */ abstract class ReaderMapper extends QBMapper { - /** - * @var Time - */ - private $time; + private Time $time; - public function __construct(IDBConnection $db, $table, $entity, Time $time) { - parent::__construct($db, $table, $entity); - $this->time = $time; - } + /** + * @param IDBConnection $db Instance of the Db abstraction layer + * @param string $table the name of the table. set this to allow entity + * @param class-string $entity the name of the entity that the sql should be mapped to queries without using sql + * @param Time $time + */ + public function __construct(IDBConnection $db, string $table, string $entity, Time $time) { + parent::__construct($db, $table, $entity); + $this->time = $time; + } - public function update(Entity $entity): Entity { - $entity->setLastModified($this->time->getMicroTime()); - return parent::update($entity); - } + public function update(Entity $entity): Entity { + $entity->setLastModified($this->time->getMicroTime()); + return parent::update($entity); + } - public function insert(Entity $entity): Entity { - $entity->setLastModified($this->time->getMicroTime()); - return parent::insert($entity); - } -} + public function insert(Entity $entity): Entity { + $entity->setLastModified($this->time->getMicroTime()); + return parent::insert($entity); + } +} diff --git a/lib/Hooks.php b/lib/Hooks.php index 9c638d1..7c9411c 100644 --- a/lib/Hooks.php +++ b/lib/Hooks.php @@ -10,61 +10,79 @@ namespace OCA\Epubreader; -use OCP\IDBConnection; +use OCA\Epubreader\AppInfo\Application; +use OCP\Files\IRootFolder; use OCP\Files\Node; +use OCP\IConfig; +use OCP\IDBConnection; use OCP\IUser; -use OCP\Util; -use \OC\User\User as User; +use OCP\IUserSession; +use OCP\Server; class Hooks { - public static function register() { - Util::connectHook('\OCP\Config', 'js', 'OCA\Epubreader\Hooks', 'announce_settings'); + private IRootFolder $rootFolder; + private IDBConnection $dbConnection; - \OC::$server->getRootFolder()->listen('\OC\Files', 'preDelete', function (Node $node) { - $fileId = $node->getId(); - $connection = \OC::$server->getDatabaseConnection(); - self::deleteFile($connection, $fileId); - }); - \OC::$server->getUserManager()->listen('\OC\User', 'preDelete', function (User $user) { - $userId = $user->getUID(); - $connection = \OC::$server->getDatabaseConnection(); - self::deleteUser($connection, $userId); - }); - } + public function __construct( + IRootFolder $rootFolder, + IDBConnection $dbConnection, + ) { + $this->rootFolder = $rootFolder; + $this->dbConnection = $dbConnection; + } - public static function announce_settings(array $settings) { - // Nextcloud encodes this as JSON, Owncloud does not (yet) (#75) - // TODO: rmeove this when Owncloud starts encoding oc_appconfig as JSON just like it already encodes most other properties - $isJson = self::isJson($settings['array']['oc_appconfig']); - $array = ($isJson) ? json_decode($settings['array']['oc_appconfig'], true) : $settings['array']['oc_appconfig']; - $array['filesReader']['enableEpub'] = Config::get('epub_enable', 'true'); - $array['filesReader']['enablePdf'] = Config::get('pdf_enable', 'true'); - $array['filesReader']['enableCbx'] = Config::get('cbx_enable', 'true'); - $settings['array']['oc_appconfig'] = ($isJson) ? json_encode($array) : $array; - } + public function register(): void { + $this->rootFolder->listen('\OC\Files', 'preDelete', function (Node $node) { + $this->deleteFile($node->getId()); + }); - protected static function deleteFile(IDBConnection $connection, $fileId) { - $queryBuilder = $connection->getQueryBuilder(); - $queryBuilder->delete('reader_bookmarks')->where('file_id = file_id')->setParameter('file_id', $fileId); - $queryBuilder->execute(); + $this->rootFolder->listen('\OC\User', 'preDelete', function (IUser $user) { + $this->deleteUser($user->getUID()); + }); + } - $queryBuilder = $connection->getQueryBuilder(); - $queryBuilder->delete('reader_prefs')->where('file_id = file_id')->setParameter('file_id', $fileId); - $queryBuilder->execute(); - } + public static function announce_settings(array $settings): void { + // Nextcloud encodes this as JSON, Owncloud does not (yet) (#75) + // TODO: remove this when Owncloud starts encoding oc_appconfig as JSON just like it already encodes most other properties + $user = Server::get(IUserSession::class)->getUser(); + if ($user && + is_array($settings['array']) && + array_key_exists('oc_appconfig', $settings['array']) + ) { + $isJson = self::isJson($settings['array']['oc_appconfig']); + /** @var array $array */ + $array = ($isJson) ? json_decode((string) $settings['array']['oc_appconfig'], true) : $settings['array']['oc_appconfig']; + $array['filesReader'] = [ + 'enableEpub' => Server::get(IConfig::class)->getUserValue($user->getUID(), Application::APP_ID, 'epub_enable', true), + 'enablePdf' => Server::get(IConfig::class)->getUserValue($user->getUID(), Application::APP_ID, 'pdf_enable', true), + 'enableCbx' => Server::get(IConfig::class)->getUserValue($user->getUID(), Application::APP_ID, 'cbx_enable', true), + ]; + $settings['array']['oc_appconfig'] = ($isJson) ? json_encode($array) : $array; + } + } - protected static function deleteUser(IDBConnection $connection, $userId) { - $queryBuilder = $connection->getQueryBuilder(); - $queryBuilder->delete('reader_bookmarks')->where('user_id = user_id')->setParameter('user_id', $userId); - $queryBuilder->execute(); + protected function deleteFile(int $fileId): void { + $queryBuilder = $this->dbConnection->getQueryBuilder(); + $queryBuilder->delete('reader_bookmarks')->where('file_id = file_id')->setParameter('file_id', $fileId); + $queryBuilder->executeStatement(); - $queryBuilder = $connection->getQueryBuilder(); - $queryBuilder->delete('reader_prefs')->where('user_id = user_id')->setParameter('user_id', $userId); - $queryBuilder->execute(); - } + $queryBuilder = $this->dbConnection->getQueryBuilder(); + $queryBuilder->delete('reader_prefs')->where('file_id = file_id')->setParameter('file_id', $fileId); + $queryBuilder->executeStatement(); + } - private static function isJson($string) { - return is_string($string) && is_array(json_decode($string, true)) && (json_last_error() == JSON_ERROR_NONE) ? true : false; - } + protected function deleteUser(string $userId): void { + $queryBuilder = $this->dbConnection->getQueryBuilder(); + $queryBuilder->delete('reader_bookmarks')->where('user_id = user_id')->setParameter('user_id', $userId); + $queryBuilder->executeStatement(); + + $queryBuilder = $this->dbConnection->getQueryBuilder(); + $queryBuilder->delete('reader_prefs')->where('user_id = user_id')->setParameter('user_id', $userId); + $queryBuilder->executeStatement(); + } + + private static function isJson(mixed $string): bool { + return is_string($string) && is_array(json_decode($string, true)) && json_last_error() == JSON_ERROR_NONE; + } } diff --git a/lib/Migration/Version010404Date20201030180941.php b/lib/Migration/Version010404Date20201030180941.php index 98b2c49..8b56db3 100644 --- a/lib/Migration/Version010404Date20201030180941.php +++ b/lib/Migration/Version010404Date20201030180941.php @@ -19,16 +19,15 @@ class Version010404Date20201030180941 extends SimpleMigrationStep { * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` * @param array $options */ - public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { + public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { } /** * @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) { + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { /** @var ISchemaWrapper $schema */ $schema = $schemaClosure(); @@ -138,6 +137,6 @@ class Version010404Date20201030180941 extends SimpleMigrationStep { * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` * @param array $options */ - public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { } } diff --git a/lib/Service/BookmarkService.php b/lib/Service/BookmarkService.php index 92fb79c..860e8eb 100644 --- a/lib/Service/BookmarkService.php +++ b/lib/Service/BookmarkService.php @@ -10,104 +10,103 @@ namespace OCA\Epubreader\Service; - use OCA\Epubreader\Db\BookmarkMapper; +use OCA\Epubreader\Db\ReaderEntity; +/** + * @psalm-import-type SerializedEntity from ReaderEntity + */ class BookmarkService extends Service { - // "bookmark" name to use for the cursor (current reading position) - const CURSOR = '__CURSOR__'; - const bookmark_type = 'bookmark'; + // "bookmark" name to use for the cursor (current reading position) + private const CURSOR = '__CURSOR__'; + private const BOOKMARK_TYPE = 'bookmark'; - private $bookmarkMapper; - private $userId; + private BookmarkMapper $bookmarkMapper; - public function __construct(BookmarkMapper $bookmarkMapper, $UserId) { - parent::__construct($bookmarkMapper); - $this->bookmarkMapper = $bookmarkMapper; - $this->userId = $UserId; - } + public function __construct(BookmarkMapper $bookmarkMapper) { + parent::__construct($bookmarkMapper); + $this->bookmarkMapper = $bookmarkMapper; + } - /** - * @brief get bookmark - * - * bookmark type is format-dependent, eg CFI for epub, page number for CBR/CBZ, etc - * - * @param int $fileId - * @param string $name - * - * @return array - */ - public function get($fileId, $name=null, $type=null) { - $result = $this->bookmarkMapper->get($fileId, $name, $type); - return array_map( - function($entity) { - return $entity->toService(); - }, $result); - } + /** + * @brief get bookmark + * + * bookmark type is format-dependent, eg CFI for epub, page number for CBR/CBZ, etc + * + * @param int $fileId + * @param ?string $name + * @param ?string $type + * + * @psalm-return SerializedEntity[] + */ + public function get($fileId, ?string $name = null, ?string $type = null): array { + $result = $this->bookmarkMapper->get($fileId, $name, $type); + return array_map( + function (ReaderEntity $entity): array { + return $entity->toService(); + }, $result); + } - /** - * @brief write bookmark - * - * position type is format-dependent, eg CFI for epub, page number for CBR/CBZ, etc - * - * @param int $fileId - * @param string $name - * @param string $value - * - * @return array - */ - public function set($fileId, $name, $value, $type=null, $content=null) { - return $this->bookmarkMapper->set($fileId, $name, $value, $type, $content); - } + /** + * @brief write bookmark + * + * position type is format-dependent, eg CFI for epub, page number for CBR/CBZ, etc + * + * @param int $fileId + * @param string $name + * @param string $value + * @param ?string $type + * @param ?string $content + */ + public function set(int $fileId, string $name, string $value, ?string $type = null, ?string $content = null): ReaderEntity { + return $this->bookmarkMapper->set($fileId, $name, $value, $type, $content); + } - /** - * @brief get cursor (current position in book) - * - * @param int $fileId - * - * @return array - */ - public function getCursor($fileId) { - $result = $this->get($fileId, static::CURSOR); - if (count($result) === 1) { - return $result[0]; - } - } + /** + * @brief get cursor (current position in book) + * + * @param int $fileId + * + * @psalm-return SerializedEntity + */ + public function getCursor(int $fileId): array { + $result = $this->get($fileId, self::CURSOR); + if (count($result) === 1) { + return $result[0]; + } + return []; + } - /** - * @brief set cursor (current position in book) - * - * @param int $fileId - * @param string $value - * - * @return array - */ - public function setCursor($fileId, $value) { - return $this->bookmarkMapper->set($fileId, static::CURSOR, $value, static::bookmark_type); - } + /** + * @brief set cursor (current position in book) + * + * @param int $fileId + * @param string $value + */ + public function setCursor(int $fileId, string $value): ReaderEntity { + return $this->bookmarkMapper->set($fileId, self::CURSOR, $value, self::BOOKMARK_TYPE); + } - /** - * @brief delete bookmark - * - * @param int $fileId - * @param string $name - * - */ - public function delete($fileId, $name, $type=null) { - foreach ($this->bookmarkMapper->get($fileId, $name, $type) as $bookmark) { - $this->bookmarkMapper->delete($bookmark); - } - } + /** + * @brief delete bookmark + * + * @param int $fileId + * @param ?string $name + * @param ?string $type + */ + public function delete($fileId, ?string $name = null, ?string $type = null): void { + foreach ($this->bookmarkMapper->get($fileId, $name, $type) as $bookmark) { + $this->bookmarkMapper->delete($bookmark); + } + } - /** - * @brief delete cursor - * - * @param int $fileId - * - */ - public function deleteCursor($fileId) { - $this->delete($fileId, static::CURSOR, static::bookmark_type); - } + /** + * @brief delete cursor + * + * @param int $fileId + */ + public function deleteCursor(int $fileId): void { + $this->delete($fileId, self::CURSOR, self::BOOKMARK_TYPE); + } } - diff --git a/lib/Service/MetadataService.php b/lib/Service/MetadataService.php deleted file mode 100644 index bbf85e3..0000000 --- a/lib/Service/MetadataService.php +++ /dev/null @@ -1,75 +0,0 @@ -appManager = $appManager; - } - - /** - * @brief get metadata item(s) - * - * @param int $fileId - * @param string $name - * - * @return array - */ - public function get($fileId, $name=null) { - if ($this->appManager->isInstalled('files_opds')) { - if ($meta = \OCA\Files_Opds\Meta::get($fileId)) { - if (!empty($name) && array_key_exists($name, $meta)) { - return [$item => $meta[$name]]; - } else { - return $meta; - } - } - } - - return []; - } - - /** - * @brief write metadata to database - * - * @param int $fileId - * @param array $value - * - * @return array - */ - public function setAll($fileId, $value) { - // no-op for now - return []; - } - - /** - * @brief write metadata item to database - * - * @param int $fileId - * @param string $name - * @param array $value - * - * @return array - */ - public function set($fileId, $name, $value) { - // no-op for now - return []; - } -} - diff --git a/lib/Service/PreferenceService.php b/lib/Service/PreferenceService.php index d26eb63..7ceb5e8 100644 --- a/lib/Service/PreferenceService.php +++ b/lib/Service/PreferenceService.php @@ -11,107 +11,105 @@ namespace OCA\Epubreader\Service; use OCA\Epubreader\Db\PreferenceMapper; +use OCA\Epubreader\Db\ReaderEntity; +/** + * @psalm-import-type SerializedEntity from ReaderEntity + */ class PreferenceService extends Service { - // (ab)use the fact that $fileId never goes below 1 by using the - // value 0 to indicate a default preference - const DEFAULTS = 0; + // (ab)use the fact that $fileId never goes below 1 by using the + // value 0 to indicate a default preference + private const DEFAULTS = 0; - private $preferenceMapper; + private PreferenceMapper $preferenceMapper; - /** - * @param PreferenceMapper $preferenceMapper - */ - public function __construct(PreferenceMapper $preferenceMapper) { - parent::__construct($preferenceMapper); - $this->preferenceMapper = $preferenceMapper; - } + /** + * @param PreferenceMapper $preferenceMapper + */ + public function __construct(PreferenceMapper $preferenceMapper) { + parent::__construct($preferenceMapper); + $this->preferenceMapper = $preferenceMapper; + } - /** - * @brief get preference - * - * scope identifies preference source, i.e. which renderer the preference applies to - * preference type is format-dependent, eg CFI for epub, page number for CBR/CBZ, etc - * - * @param string $scope - * @param int $fileId - * @param string $name - * - * @return array - */ - public function get($scope, $fileId, $name=null) { - $result = $this->preferenceMapper->get($scope, $fileId, $name); - return array_map( - function($entity) { - return $entity->toService(); - }, $result); - } + /** + * @brief get preference + * + * scope identifies preference source, i.e. which renderer the preference applies to + * preference type is format-dependent, eg CFI for epub, page number for CBR/CBZ, etc + * + * @param string $scope + * @param int $fileId + * @param ?string $name + * + * @psalm-return SerializedEntity + */ + public function get(string $scope, int $fileId, ?string $name = null): array { + $result = $this->preferenceMapper->get($scope, $fileId, $name); + return array_map( + function (ReaderEntity $entity): array { + return $entity->toService(); + }, $result); + } - /** - * @brief write preference - * - * scope identifies preference source, i.e. which renderer the preference applies to - * position type is format-dependent, eg CFI for epub, page number for CBR/CBZ, etc - * - * @param string $scope - * @param int $fileId - * @param string $name - * @param string $value - * - * @return array - */ - public function set($scope, $fileId, $name, $value) { - return $this->preferenceMapper->set($scope, $fileId, $name, $value); - } + /** + * @brief write preference + * + * scope identifies preference source, i.e. which renderer the preference applies to + * position type is format-dependent, eg CFI for epub, page number for CBR/CBZ, etc + * + * @param string $scope + * @param int $fileId + * @param string $name + * @param string $value + */ + public function set(string $scope, int $fileId, string $name, string $value): ReaderEntity { + return $this->preferenceMapper->set($scope, $fileId, $name, $value); + } - /** - * @brief get default preference - * - * @param string $scope - * @param string $name - * - * @return array - */ - public function getDefault($scope, $name=null) { - return $this->get($scope, static::DEFAULTS, $name); - } + /** + * @brief get default preference + * + * @param string $scope + * @param ?string $name + */ + public function getDefault(string $scope, ?string $name = null): array { + return $this->get($scope, self::DEFAULTS, $name); + } - /** - * @brief set default preference - * - * @param string $scope - * @param string $name - * @param string $value - * - * @return array - */ - public function setDefault($scope, $name, $value) { - return $this->preferenceMapper->set($scope, static::DEFAULTS, $name, $value); - } + /** + * @brief set default preference + * + * @param string $scope + * @param string $name + * @param string $value + */ + public function setDefault($scope, $name, $value): ReaderEntity { + return $this->preferenceMapper->set($scope, self::DEFAULTS, $name, $value); + } - /** - * @brief delete preference - * - * @param string $scope - * @param int $fileId - * @param string $name - * - */ - public function delete($scope, $fileId, $name) { - foreach($this->preferenceMapper->get($scope, $fileId, $name) as $preference) { - $this->preferenceMapper->delete($preference); - } - } + /** + * @brief delete preference + * + * @param string $scope + * @param int $fileId + * @param ?string $name + * + */ + public function delete(string $scope, int $fileId, ?string $name = null): void { + foreach($this->preferenceMapper->get($scope, $fileId, $name) as $preference) { + $this->preferenceMapper->delete($preference); + } + } - /** - * @brief delete default - * - * @param string $scope - * @param string $name - * - */ - public function deleteDefault($scope, $name) { - $this->delete($scope, static::DEFAULTS, $name); - } + /** + * @brief delete default + * + * @param string $scope + * @param ?string $name + * + */ + public function deleteDefault(string $scope, ?string $name = null): void { + $this->delete($scope, self::DEFAULTS, $name); + } } diff --git a/lib/Service/Service.php b/lib/Service/Service.php index fafdc6a..2b861e1 100644 --- a/lib/Service/Service.php +++ b/lib/Service/Service.php @@ -13,13 +13,9 @@ namespace OCA\Epubreader\Service; use OCA\Epubreader\Db\ReaderMapper; abstract class Service { + protected ReaderMapper $mapper; - protected $mapper; - - public function __construct(ReaderMapper $mapper){ - $this->mapper = $mapper; - } + public function __construct(ReaderMapper $mapper) { + $this->mapper = $mapper; + } } - - - diff --git a/lib/Settings/Personal.php b/lib/Settings/Personal.php index dbfccb1..6d1291e 100644 --- a/lib/Settings/Personal.php +++ b/lib/Settings/Personal.php @@ -11,79 +11,73 @@ namespace OCA\Epubreader\Settings; +use OCA\Epubreader\AppInfo\Application; use OCP\AppFramework\Http\TemplateResponse; -use OCP\Settings\ISettings; use OCP\IConfig; +use OCP\Settings\ISettings; -class Personal implements ISettings -{ +class Personal implements ISettings { - private $userId; - private $configManager; + private string $userId; + private IConfig $configManager; - public function __construct( - $userId, - IConfig $configManager - ) - { - $this->userId = $userId; - $this->configManager = $configManager; - } + public function __construct( + string $userId, + IConfig $configManager + ) { + $this->userId = $userId; + $this->configManager = $configManager; + } - /** - * @return TemplateResponse returns the instance with all parameters set, ready to be rendered - * @since 9.1 - */ - public function getForm() - { + /** + * @return TemplateResponse returns the instance with all parameters set, ready to be rendered + * @since 9.1 + */ + public function getForm(): TemplateResponse { + $parameters = [ + 'EpubEnable' => $this->configManager->getUserValue($this->userId, Application::APP_ID, 'epub_enable', 'true'), + 'PdfEnable' => $this->configManager->getUserValue($this->userId, Application::APP_ID, 'pdf_enable', 'true'), + 'CbxEnable' => $this->configManager->getUserValue($this->userId, Application::APP_ID, 'cbx_enable', 'true'), + ]; - $parameters = [ - 'EpubEnable' => $this->configManager->getUserValue($this->userId, 'epubreader', 'epub_enable'), - 'PdfEnable' => $this->configManager->getUserValue($this->userId, 'epubreader', 'pdf_enable'), - 'CbxEnable' => $this->configManager->getUserValue($this->userId, 'epubreader', 'cbx_enable'), - ]; - return new TemplateResponse('epubreader', 'settings-personal', $parameters, ''); - } + return new TemplateResponse(Application::APP_ID, 'settings-personal', $parameters, ''); + } - /** - * Print config section (ownCloud 10) - * - * @return TemplateResponse - */ - public function getPanel() - { - return $this->getForm(); - } + /** + * Print config section (ownCloud 10) + * + * @return TemplateResponse + */ + public function getPanel(): TemplateResponse { + return $this->getForm(); + } - /** - * @return string the section ID, e.g. 'sharing' - * @since 9.1 - */ - public function getSection() - { - return 'epubreader'; - } + /** + * @return string the section ID, e.g. 'sharing' + * @since 9.1 + */ + public function getSection(): string { + return Application::APP_ID; + } - /** - * Get section ID (ownCloud 10) - * - * @return string - */ - public function getSectionID() - { - return 'epubreader'; - } + /** + * Get section ID (ownCloud 10) + * + * @return string + */ + public function getSectionID(): string { + return Application::APP_ID; + } - /** - * @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 - * @since 9.1 - */ - public function getPriority() - { - return 10; - } + /** + * @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 + * @since 9.1 + */ + public function getPriority(): int { + return 10; + } } diff --git a/lib/Settings/PersonalSection.php b/lib/Settings/PersonalSection.php index 17d8d64..7cbc202 100644 --- a/lib/Settings/PersonalSection.php +++ b/lib/Settings/PersonalSection.php @@ -11,60 +11,54 @@ namespace OCA\Epubreader\Settings; +use OCA\Epubreader\AppInfo\Application; use OCP\IL10N; use OCP\IURLGenerator; use OCP\Settings\IIconSection; -class PersonalSection implements IIconSection -{ - /** @var IURLGenerator */ - private $urlGenerator; - /** @var IL10N */ - private $l; +class PersonalSection implements IIconSection { - public function __construct(IURLGenerator $urlGenerator, IL10N $l) - { - $this->urlGenerator = $urlGenerator; - $this->l = $l; - } + private IURLGenerator $urlGenerator; + private IL10N $l; - /** - * returns the relative path to an 16*16 icon describing the section. - * - * @returns string - */ - public function getIcon() - { - return $this->urlGenerator->imagePath('epubreader', 'app.svg'); - } + public function __construct(IURLGenerator $urlGenerator, IL10N $l) { + $this->urlGenerator = $urlGenerator; + $this->l = $l; + } - /** - * returns the ID of the section. It is supposed to be a lower case string, - * - * @returns string - */ - public function getID() - { - return 'epubreader'; - } + /** + * returns the relative path to an 16*16 icon describing the section. + * + * @return string + */ + public function getIcon(): string { + return $this->urlGenerator->imagePath(Application::APP_ID, 'app.svg'); + } - /** - * returns the translated name as it should be displayed - * - * @return string - */ - public function getName() - { - return $this->l->t('EPUB/CBZ/PDF ebook reader'); - } + /** + * returns the ID of the section. It is supposed to be a lower case string, + * + * @return string + */ + public function getID(): string { + return Application::APP_ID; + } - /** - * returns priority for positioning - * - * @return int - */ - public function getPriority() - { - return 20; - } -} \ No newline at end of file + /** + * returns the translated name as it should be displayed + * + * @return string + */ + public function getName(): string { + return $this->l->t('EPUB/CBZ/PDF ebook reader'); + } + + /** + * returns priority for positioning + * + * @return int + */ + public function getPriority(): int { + return 20; + } +} diff --git a/lib/Utility/Time.php b/lib/Utility/Time.php index 8ed5243..fecbaf7 100644 --- a/lib/Utility/Time.php +++ b/lib/Utility/Time.php @@ -11,17 +11,16 @@ namespace OCA\Epubreader\Utility; class Time { - public function getTime() { - return time(); - } - /** - * - * @return int the current unix time in miliseconds - */ - public function getMicroTime() { - list($millisecs, $secs) = explode(" ", microtime()); - return $secs . substr($millisecs, 2, 6); - } + public function getTime(): int { + return time(); + } -} + /** + * @return int the current unix time in miliseconds + */ + public function getMicroTime(): int { + list($millisecs, $secs) = explode(' ', microtime()); + return (int) ($secs . substr($millisecs, 2, 6)); + } +} diff --git a/lib/config.php b/lib/config.php deleted file mode 100644 index 4f0474d..0000000 --- a/lib/config.php +++ /dev/null @@ -1,63 +0,0 @@ -getConfig()->getUserValue(\OC_User::getUser(), 'epubreader', $key, $default); - } - - /** - * @brief set user config value - * - * @param string $key key for value to change - * @param string $value value to use - * @return bool success - */ - public static function set($key, $value) { - return \OC::$server->getConfig()->setUserValue(\OC_User::getUser(), 'epubreader', $key, $value); - } - - /** - * @brief get app config value - * - * @param string $key value to retrieve - * @param string $default default value to use - * @return string retrieved value or default - */ - public static function getApp($key, $default) { - return \OC::$server->getConfig()->getAppValue('epubreader', $key, $default); - } - - /** - * @brief set app config value - * - * @param string $key key for value to change - * @param string $value value to use - * @return bool success - */ - public static function setApp($key, $value) { - return \OC::$server->getConfig()->setAppValue('epubreader', $key, $value); - } -} diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..8b21fed --- /dev/null +++ b/psalm.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/bartaz/jquery.highlight.js b/public/bartaz/jquery.highlight.js similarity index 100% rename from vendor/bartaz/jquery.highlight.js rename to public/bartaz/jquery.highlight.js diff --git a/vendor/bgrins/spectrum.css b/public/bgrins/spectrum.css similarity index 100% rename from vendor/bgrins/spectrum.css rename to public/bgrins/spectrum.css diff --git a/vendor/bgrins/spectrum.js b/public/bgrins/spectrum.js similarity index 100% rename from vendor/bgrins/spectrum.js rename to public/bgrins/spectrum.js diff --git a/vendor/bitjs/archive/archive.js b/public/bitjs/archive/archive.js similarity index 100% rename from vendor/bitjs/archive/archive.js rename to public/bitjs/archive/archive.js diff --git a/vendor/bitjs/archive/rarvm.js b/public/bitjs/archive/rarvm.js similarity index 100% rename from vendor/bitjs/archive/rarvm.js rename to public/bitjs/archive/rarvm.js diff --git a/vendor/bitjs/archive/unrar.js b/public/bitjs/archive/unrar.js similarity index 100% rename from vendor/bitjs/archive/unrar.js rename to public/bitjs/archive/unrar.js diff --git a/vendor/bitjs/archive/untar.js b/public/bitjs/archive/untar.js similarity index 100% rename from vendor/bitjs/archive/untar.js rename to public/bitjs/archive/untar.js diff --git a/vendor/bitjs/archive/unzip.js b/public/bitjs/archive/unzip.js similarity index 100% rename from vendor/bitjs/archive/unzip.js rename to public/bitjs/archive/unzip.js diff --git a/vendor/bitjs/io/bitstream.js b/public/bitjs/io/bitstream.js similarity index 100% rename from vendor/bitjs/io/bitstream.js rename to public/bitjs/io/bitstream.js diff --git a/vendor/bitjs/io/bytebuffer.js b/public/bitjs/io/bytebuffer.js similarity index 100% rename from vendor/bitjs/io/bytebuffer.js rename to public/bitjs/io/bytebuffer.js diff --git a/vendor/bitjs/io/bytestream.js b/public/bitjs/io/bytestream.js similarity index 100% rename from vendor/bitjs/io/bytestream.js rename to public/bitjs/io/bytestream.js diff --git a/vendor/cbrjs/cbr.js b/public/cbrjs/cbr.js similarity index 99% rename from vendor/cbrjs/cbr.js rename to public/cbrjs/cbr.js index e866d25..9c9bcd1 100644 --- a/vendor/cbrjs/cbr.js +++ b/public/cbrjs/cbr.js @@ -73,7 +73,7 @@ CBRJS.Reader = function(bookPath, _options) { xhr.onload = function () { if ((this.status === 200) && this.response) { var done = false; - var ua = new bitjs.archive[archive_class](this.response, document.head.dataset.staticpath + 'vendor/bitjs/'); + var ua = new bitjs.archive[archive_class](this.response, document.head.dataset.staticpath + 'public/bitjs/'); ua.addEventListener(bitjs.archive.UnarchiveEvent.Type.START, function (e) { $progressbar.css('width', '0%'); @@ -276,7 +276,7 @@ ComicBook = (function ($) { 70: 'toggleFullscreen', // f 27: 'closeSidebar' // esc }, - vendorPath: document.head.dataset.staticpath + 'vendor/', + vendorPath: document.head.dataset.staticpath + 'public/', forward_buffer: 3, session: { getCursor: function() {}, diff --git a/vendor/cbrjs/css/cbr.css b/public/cbrjs/css/cbr.css similarity index 100% rename from vendor/cbrjs/css/cbr.css rename to public/cbrjs/css/cbr.css diff --git a/vendor/cbrjs/css/idevice.css b/public/cbrjs/css/idevice.css similarity index 100% rename from vendor/cbrjs/css/idevice.css rename to public/cbrjs/css/idevice.css diff --git a/vendor/cbrjs/img/loading.gif b/public/cbrjs/img/loading.gif similarity index 100% rename from vendor/cbrjs/img/loading.gif rename to public/cbrjs/img/loading.gif diff --git a/vendor/epubjs/css/annotations.css b/public/epubjs/css/annotations.css similarity index 100% rename from vendor/epubjs/css/annotations.css rename to public/epubjs/css/annotations.css diff --git a/vendor/epubjs/css/font/fontello.eot b/public/epubjs/css/font/fontello.eot similarity index 100% rename from vendor/epubjs/css/font/fontello.eot rename to public/epubjs/css/font/fontello.eot diff --git a/vendor/epubjs/css/font/fontello.svg b/public/epubjs/css/font/fontello.svg similarity index 100% rename from vendor/epubjs/css/font/fontello.svg rename to public/epubjs/css/font/fontello.svg diff --git a/vendor/epubjs/css/font/fontello.ttf b/public/epubjs/css/font/fontello.ttf similarity index 100% rename from vendor/epubjs/css/font/fontello.ttf rename to public/epubjs/css/font/fontello.ttf diff --git a/vendor/epubjs/css/font/fontello.woff b/public/epubjs/css/font/fontello.woff similarity index 100% rename from vendor/epubjs/css/font/fontello.woff rename to public/epubjs/css/font/fontello.woff diff --git a/vendor/epubjs/css/idevice.css b/public/epubjs/css/idevice.css similarity index 100% rename from vendor/epubjs/css/idevice.css rename to public/epubjs/css/idevice.css diff --git a/vendor/epubjs/css/main.css b/public/epubjs/css/main.css similarity index 100% rename from vendor/epubjs/css/main.css rename to public/epubjs/css/main.css diff --git a/vendor/epubjs/css/normalize.css b/public/epubjs/css/normalize.css similarity index 100% rename from vendor/epubjs/css/normalize.css rename to public/epubjs/css/normalize.css diff --git a/vendor/epubjs/css/popup.css b/public/epubjs/css/popup.css similarity index 100% rename from vendor/epubjs/css/popup.css rename to public/epubjs/css/popup.css diff --git a/vendor/epubjs/css/sidebar.css b/public/epubjs/css/sidebar.css similarity index 100% rename from vendor/epubjs/css/sidebar.css rename to public/epubjs/css/sidebar.css diff --git a/vendor/epubjs/epub.main.css b/public/epubjs/epub.main.css similarity index 100% rename from vendor/epubjs/epub.main.css rename to public/epubjs/epub.main.css diff --git a/vendor/epubjs/epub.min.js b/public/epubjs/epub.min.js similarity index 100% rename from vendor/epubjs/epub.min.js rename to public/epubjs/epub.min.js diff --git a/vendor/epubjs/epub.min.map b/public/epubjs/epub.min.map similarity index 100% rename from vendor/epubjs/epub.min.map rename to public/epubjs/epub.min.map diff --git a/vendor/epubjs/hooks.min.js b/public/epubjs/hooks.min.js similarity index 100% rename from vendor/epubjs/hooks.min.js rename to public/epubjs/hooks.min.js diff --git a/vendor/epubjs/hooks.min.map b/public/epubjs/hooks.min.map similarity index 100% rename from vendor/epubjs/hooks.min.map rename to public/epubjs/hooks.min.map diff --git a/vendor/epubjs/hooks/default/smartimages.js b/public/epubjs/hooks/default/smartimages.js similarity index 100% rename from vendor/epubjs/hooks/default/smartimages.js rename to public/epubjs/hooks/default/smartimages.js diff --git a/vendor/epubjs/hooks/extensions/highlight.js b/public/epubjs/hooks/extensions/highlight.js similarity index 100% rename from vendor/epubjs/hooks/extensions/highlight.js rename to public/epubjs/hooks/extensions/highlight.js diff --git a/vendor/epubjs/libs/jquery.min.js b/public/epubjs/libs/jquery.min.js similarity index 100% rename from vendor/epubjs/libs/jquery.min.js rename to public/epubjs/libs/jquery.min.js diff --git a/vendor/epubjs/libs/screenfull.min.js b/public/epubjs/libs/screenfull.min.js similarity index 100% rename from vendor/epubjs/libs/screenfull.min.js rename to public/epubjs/libs/screenfull.min.js diff --git a/vendor/epubjs/libs/zip.min.js b/public/epubjs/libs/zip.min.js similarity index 100% rename from vendor/epubjs/libs/zip.min.js rename to public/epubjs/libs/zip.min.js diff --git a/vendor/epubjs/reader.min.js b/public/epubjs/reader.min.js similarity index 100% rename from vendor/epubjs/reader.min.js rename to public/epubjs/reader.min.js diff --git a/vendor/epubjs/reader.min.map b/public/epubjs/reader.min.map similarity index 100% rename from vendor/epubjs/reader.min.map rename to public/epubjs/reader.min.map diff --git a/vendor/icomoon/fonts/icomoon.eot b/public/icomoon/fonts/icomoon.eot similarity index 100% rename from vendor/icomoon/fonts/icomoon.eot rename to public/icomoon/fonts/icomoon.eot diff --git a/vendor/icomoon/fonts/icomoon.svg b/public/icomoon/fonts/icomoon.svg similarity index 100% rename from vendor/icomoon/fonts/icomoon.svg rename to public/icomoon/fonts/icomoon.svg diff --git a/vendor/icomoon/fonts/icomoon.ttf b/public/icomoon/fonts/icomoon.ttf similarity index 100% rename from vendor/icomoon/fonts/icomoon.ttf rename to public/icomoon/fonts/icomoon.ttf diff --git a/vendor/icomoon/fonts/icomoon.woff b/public/icomoon/fonts/icomoon.woff similarity index 100% rename from vendor/icomoon/fonts/icomoon.woff rename to public/icomoon/fonts/icomoon.woff diff --git a/vendor/icomoon/style.css b/public/icomoon/style.css similarity index 100% rename from vendor/icomoon/style.css rename to public/icomoon/style.css diff --git a/vendor/jquery/put-delete.js b/public/jquery/put-delete.js similarity index 100% rename from vendor/jquery/put-delete.js rename to public/jquery/put-delete.js diff --git a/vendor/pdfjs/controllers/annotationlayer_controller.js b/public/pdfjs/controllers/annotationlayer_controller.js similarity index 100% rename from vendor/pdfjs/controllers/annotationlayer_controller.js rename to public/pdfjs/controllers/annotationlayer_controller.js diff --git a/vendor/pdfjs/controllers/bookmarks_controller.js b/public/pdfjs/controllers/bookmarks_controller.js similarity index 100% rename from vendor/pdfjs/controllers/bookmarks_controller.js rename to public/pdfjs/controllers/bookmarks_controller.js diff --git a/vendor/pdfjs/controllers/controls_controller.js b/public/pdfjs/controllers/controls_controller.js similarity index 100% rename from vendor/pdfjs/controllers/controls_controller.js rename to public/pdfjs/controllers/controls_controller.js diff --git a/vendor/pdfjs/controllers/meta_controller.js b/public/pdfjs/controllers/meta_controller.js similarity index 100% rename from vendor/pdfjs/controllers/meta_controller.js rename to public/pdfjs/controllers/meta_controller.js diff --git a/vendor/pdfjs/controllers/notes_controller.js b/public/pdfjs/controllers/notes_controller.js similarity index 100% rename from vendor/pdfjs/controllers/notes_controller.js rename to public/pdfjs/controllers/notes_controller.js diff --git a/vendor/pdfjs/controllers/outline_controller.js b/public/pdfjs/controllers/outline_controller.js similarity index 100% rename from vendor/pdfjs/controllers/outline_controller.js rename to public/pdfjs/controllers/outline_controller.js diff --git a/vendor/pdfjs/controllers/progress_controller.js b/public/pdfjs/controllers/progress_controller.js similarity index 100% rename from vendor/pdfjs/controllers/progress_controller.js rename to public/pdfjs/controllers/progress_controller.js diff --git a/vendor/pdfjs/controllers/reader_controller.js b/public/pdfjs/controllers/reader_controller.js similarity index 100% rename from vendor/pdfjs/controllers/reader_controller.js rename to public/pdfjs/controllers/reader_controller.js diff --git a/vendor/pdfjs/controllers/search_controller.js b/public/pdfjs/controllers/search_controller.js similarity index 100% rename from vendor/pdfjs/controllers/search_controller.js rename to public/pdfjs/controllers/search_controller.js diff --git a/vendor/pdfjs/controllers/settings_controller.js b/public/pdfjs/controllers/settings_controller.js similarity index 100% rename from vendor/pdfjs/controllers/settings_controller.js rename to public/pdfjs/controllers/settings_controller.js diff --git a/vendor/pdfjs/controllers/sidebar_controller.js b/public/pdfjs/controllers/sidebar_controller.js similarity index 100% rename from vendor/pdfjs/controllers/sidebar_controller.js rename to public/pdfjs/controllers/sidebar_controller.js diff --git a/vendor/pdfjs/controllers/styles_controller.js b/public/pdfjs/controllers/styles_controller.js similarity index 100% rename from vendor/pdfjs/controllers/styles_controller.js rename to public/pdfjs/controllers/styles_controller.js diff --git a/vendor/pdfjs/controllers/textlayer_controller.js b/public/pdfjs/controllers/textlayer_controller.js similarity index 100% rename from vendor/pdfjs/controllers/textlayer_controller.js rename to public/pdfjs/controllers/textlayer_controller.js diff --git a/vendor/pdfjs/controllers/textlayer_controller.js.simple b/public/pdfjs/controllers/textlayer_controller.js.simple similarity index 100% rename from vendor/pdfjs/controllers/textlayer_controller.js.simple rename to public/pdfjs/controllers/textlayer_controller.js.simple diff --git a/vendor/pdfjs/controllers/toc_controller.js b/public/pdfjs/controllers/toc_controller.js similarity index 100% rename from vendor/pdfjs/controllers/toc_controller.js rename to public/pdfjs/controllers/toc_controller.js diff --git a/vendor/pdfjs/css/annotation_layer_builder.css b/public/pdfjs/css/annotation_layer_builder.css similarity index 100% rename from vendor/pdfjs/css/annotation_layer_builder.css rename to public/pdfjs/css/annotation_layer_builder.css diff --git a/vendor/pdfjs/css/annotations.css b/public/pdfjs/css/annotations.css similarity index 100% rename from vendor/pdfjs/css/annotations.css rename to public/pdfjs/css/annotations.css diff --git a/vendor/pdfjs/css/idevice.css b/public/pdfjs/css/idevice.css similarity index 100% rename from vendor/pdfjs/css/idevice.css rename to public/pdfjs/css/idevice.css diff --git a/vendor/pdfjs/css/images/annotation-check.svg b/public/pdfjs/css/images/annotation-check.svg similarity index 100% rename from vendor/pdfjs/css/images/annotation-check.svg rename to public/pdfjs/css/images/annotation-check.svg diff --git a/vendor/pdfjs/css/images/annotation-comment.svg b/public/pdfjs/css/images/annotation-comment.svg similarity index 100% rename from vendor/pdfjs/css/images/annotation-comment.svg rename to public/pdfjs/css/images/annotation-comment.svg diff --git a/vendor/pdfjs/css/images/annotation-help.svg b/public/pdfjs/css/images/annotation-help.svg similarity index 100% rename from vendor/pdfjs/css/images/annotation-help.svg rename to public/pdfjs/css/images/annotation-help.svg diff --git a/vendor/pdfjs/css/images/annotation-insert.svg b/public/pdfjs/css/images/annotation-insert.svg similarity index 100% rename from vendor/pdfjs/css/images/annotation-insert.svg rename to public/pdfjs/css/images/annotation-insert.svg diff --git a/vendor/pdfjs/css/images/annotation-key.svg b/public/pdfjs/css/images/annotation-key.svg similarity index 100% rename from vendor/pdfjs/css/images/annotation-key.svg rename to public/pdfjs/css/images/annotation-key.svg diff --git a/vendor/pdfjs/css/images/annotation-newparagraph.svg b/public/pdfjs/css/images/annotation-newparagraph.svg similarity index 100% rename from vendor/pdfjs/css/images/annotation-newparagraph.svg rename to public/pdfjs/css/images/annotation-newparagraph.svg diff --git a/vendor/pdfjs/css/images/annotation-noicon.svg b/public/pdfjs/css/images/annotation-noicon.svg similarity index 100% rename from vendor/pdfjs/css/images/annotation-noicon.svg rename to public/pdfjs/css/images/annotation-noicon.svg diff --git a/vendor/pdfjs/css/images/annotation-note.svg b/public/pdfjs/css/images/annotation-note.svg similarity index 100% rename from vendor/pdfjs/css/images/annotation-note.svg rename to public/pdfjs/css/images/annotation-note.svg diff --git a/vendor/pdfjs/css/images/annotation-paragraph.svg b/public/pdfjs/css/images/annotation-paragraph.svg similarity index 100% rename from vendor/pdfjs/css/images/annotation-paragraph.svg rename to public/pdfjs/css/images/annotation-paragraph.svg diff --git a/vendor/pdfjs/css/main.css b/public/pdfjs/css/main.css similarity index 100% rename from vendor/pdfjs/css/main.css rename to public/pdfjs/css/main.css diff --git a/vendor/pdfjs/css/normalize.css b/public/pdfjs/css/normalize.css similarity index 100% rename from vendor/pdfjs/css/normalize.css rename to public/pdfjs/css/normalize.css diff --git a/vendor/pdfjs/css/popup.css b/public/pdfjs/css/popup.css similarity index 100% rename from vendor/pdfjs/css/popup.css rename to public/pdfjs/css/popup.css diff --git a/vendor/pdfjs/css/sidebar.css b/public/pdfjs/css/sidebar.css similarity index 100% rename from vendor/pdfjs/css/sidebar.css rename to public/pdfjs/css/sidebar.css diff --git a/vendor/pdfjs/css/text_layer_builder.css b/public/pdfjs/css/text_layer_builder.css similarity index 100% rename from vendor/pdfjs/css/text_layer_builder.css rename to public/pdfjs/css/text_layer_builder.css diff --git a/vendor/pdfjs/lib/pdf.js b/public/pdfjs/lib/pdf.js similarity index 100% rename from vendor/pdfjs/lib/pdf.js rename to public/pdfjs/lib/pdf.js diff --git a/vendor/pdfjs/lib/pdf.worker.js b/public/pdfjs/lib/pdf.worker.js similarity index 100% rename from vendor/pdfjs/lib/pdf.worker.js rename to public/pdfjs/lib/pdf.worker.js diff --git a/vendor/pdfjs/lib/text_layer_builder.js b/public/pdfjs/lib/text_layer_builder.js similarity index 100% rename from vendor/pdfjs/lib/text_layer_builder.js rename to public/pdfjs/lib/text_layer_builder.js diff --git a/vendor/pdfjs/pdf.reader.js b/public/pdfjs/pdf.reader.js similarity index 100% rename from vendor/pdfjs/pdf.reader.js rename to public/pdfjs/pdf.reader.js diff --git a/vendor/pdfjs/services/eventbus_service.js b/public/pdfjs/services/eventbus_service.js similarity index 100% rename from vendor/pdfjs/services/eventbus_service.js rename to public/pdfjs/services/eventbus_service.js diff --git a/vendor/pdfjs/services/link_service.js b/public/pdfjs/services/link_service.js similarity index 100% rename from vendor/pdfjs/services/link_service.js rename to public/pdfjs/services/link_service.js diff --git a/vendor/pdfjs/services/simple_link_service.js b/public/pdfjs/services/simple_link_service.js similarity index 100% rename from vendor/pdfjs/services/simple_link_service.js rename to public/pdfjs/services/simple_link_service.js diff --git a/vendor/pixastic/pixastic.effects.js b/public/pixastic/pixastic.effects.js similarity index 100% rename from vendor/pixastic/pixastic.effects.js rename to public/pixastic/pixastic.effects.js diff --git a/vendor/pixastic/pixastic.js b/public/pixastic/pixastic.js similarity index 100% rename from vendor/pixastic/pixastic.js rename to public/pixastic/pixastic.js diff --git a/vendor/pixastic/pixastic.worker.control.js b/public/pixastic/pixastic.worker.control.js similarity index 100% rename from vendor/pixastic/pixastic.worker.control.js rename to public/pixastic/pixastic.worker.control.js diff --git a/vendor/pixastic/pixastic.worker.js b/public/pixastic/pixastic.worker.js similarity index 100% rename from vendor/pixastic/pixastic.worker.js rename to public/pixastic/pixastic.worker.js diff --git a/vendor/pixastic/pixastic_combined.js b/public/pixastic/pixastic_combined.js similarity index 94% rename from vendor/pixastic/pixastic_combined.js rename to public/pixastic/pixastic_combined.js index 0c7c5d4..c15fa5b 100644 --- a/vendor/pixastic/pixastic_combined.js +++ b/public/pixastic/pixastic_combined.js @@ -4,13 +4,13 @@ * Pixastic - JavaScript Image Processing * http://pixastic.com/ * Copyright 2012, Jacob Seidelin - * + * * Dual licensed under the MPL 1.1 or GPLv3 licenses. * http://pixastic.com/license-mpl.txt * http://pixastic.com/license-gpl-3.0.txt * */ - + var Pixastic = (function() { var worker; @@ -22,14 +22,14 @@ return ctx.getImageData(0, 0, width, height); } } - + function Pixastic(ctx, workerControlPath) { var P = {}, - width = ctx.canvas.width, + width = ctx.canvas.width, height = ctx.canvas.height, queue = [], - workerControlPath = workerControlPath || "vendor/pixastic/"; + workerControlPath = workerControlPath || "public/pixastic/"; if (!worker) { if (typeof window.Worker != "undefined") { @@ -47,7 +47,7 @@ worker = new Pixastic.Worker(); } } - + for (var e in Pixastic.Effects) { if (Pixastic.Effects.hasOwnProperty(e)) { (function(e) { @@ -61,7 +61,7 @@ P.done = function(callback, progress) { var inData, outData; - + try { inData = ctx.getImageData(0, 0, width, height); } catch(e) { @@ -71,21 +71,21 @@ throw new Error("Could not access image data, is canvas tainted by cross-origin data?"); } } - + outData = createImageData(ctx, width, height); - + worker.postMessage({ - queue : queue, - inData : inData, + queue : queue, + inData : inData, outData : outData, width : width, height : height }); - + worker.onmessage = function(message) { var d = message.data; switch (d.event) { - case "done" : + case "done" : ctx.putImageData(d.data, 0, 0); if (callback) { callback(); @@ -103,7 +103,7 @@ break; } }; - + if (progress) { progress(0); } @@ -149,7 +149,7 @@ } Pixastic.Effects[e](inData.data, outData.data, width, height, options, progressCallback); - + me.onmessage({ data : { event : "progress", @@ -157,7 +157,7 @@ } }); } - + me.onmessage({ data : { event : "done", @@ -171,19 +171,19 @@ processMessage(data) }, 0); }; - + this.onmessage = function() {}; }; - + Pixastic.log = function(str) { if (typeof console != "undefined" && console.log) { console.log("Pixastic: " + str); } }; - + function toCanvas(o) { var canvas; if (typeof o == "object") { @@ -224,34 +224,34 @@ round = Math.round, maxValue, n = imageData.width * imageData.height; - + for (i=0;i<256;i++) { values[i] = 0; } - + for (i=0;i maxValue) { maxValue = values[i]; } } - + return { maxValue : maxValue, values : values }; } - + Pixastic.toCanvas = toCanvas; Pixastic.toImage = toImage; Pixastic.toImageData = toImageData; Pixastic.histogram = histogram; - + Pixastic.Color = { rgb2hsl : function(r, g, b) { if (r < 0) r = 0; @@ -261,16 +261,16 @@ if (g > 255) g = 0; if (b > 255) b = 0; }, - + rgb2hsv : function(r, g, b) { }, rgb2hex : function(r, g, b) { }, - + hsl2rgb : function(h, s, l) { }, - + hsv2rgb : function(h, s, v) { } @@ -304,18 +304,18 @@ Pixastic.Effects = (function() { pyc, pyp, pyn, pxc, pxp, pxn, x, y, - + prog, lastProg = 0, n = width * height * 4, - + k00 = kernel[0][0], k01 = kernel[0][1], k02 = kernel[0][2], k10 = kernel[1][0], k11 = kernel[1][1], k12 = kernel[1][2], k20 = kernel[2][0], k21 = kernel[2][1], k22 = kernel[2][2], - + p00, p01, p02, p10, p11, p12, p20, p21, p22; - + for (y=0;y= width-1) pyn = pyc; - + for (x=0;x= width-1) pxn = pxc; - + p00 = pyp + pxp; p01 = pyp + pxc; p02 = pyp + pxn; p10 = pyc + pxp; p11 = pyc + pxc; p12 = pyc + pxn; p20 = pyn + pxp; p21 = pyn + pxc; p22 = pyn + pxn; @@ -345,7 +345,7 @@ Pixastic.Effects = (function() { g = inData[p00 + 1] * k00 + inData[p01 + 1] * k01 + inData[p02 + 1] * k02 + inData[p10 + 1] * k10 + inData[p11 + 1] * k11 + inData[p12 + 1] * k12 + inData[p20 + 1] * k20 + inData[p21 + 1] * k21 + inData[p22 + 1] * k22; - + b = inData[p00 + 2] * k00 + inData[p01 + 2] * k01 + inData[p02 + 2] * k02 + inData[p10 + 2] * k10 + inData[p11 + 2] * k11 + inData[p12 + 2] * k12 + inData[p20 + 2] * k20 + inData[p21 + 2] * k21 + inData[p22 + 2] * k22; @@ -366,12 +366,12 @@ Pixastic.Effects = (function() { g = 255 - g; b = 255 - b; } - + outData[idx] = r; outData[idx+1] = g; outData[idx+2] = b; outData[idx+3] = a; - + if (progress) { prog = (idx/n*100 >> 0) / 100; if (prog > lastProg) { @@ -381,28 +381,28 @@ Pixastic.Effects = (function() { } } } - + function convolve5x5(inData, outData, width, height, kernel, progress, alpha, invert, mono) { var idx, r, g, b, a, pyc, pyp, pyn, pypp, pynn, pxc, pxp, pxn, pxpp, pxnn, x, y, - + prog, lastProg = 0, n = width * height * 4, - + k00 = kernel[0][0], k01 = kernel[0][1], k02 = kernel[0][2], k03 = kernel[0][3], k04 = kernel[0][4], k10 = kernel[1][0], k11 = kernel[1][1], k12 = kernel[1][2], k13 = kernel[1][3], k14 = kernel[1][4], k20 = kernel[2][0], k21 = kernel[2][1], k22 = kernel[2][2], k23 = kernel[2][3], k24 = kernel[2][4], k30 = kernel[3][0], k31 = kernel[3][1], k32 = kernel[3][2], k33 = kernel[3][3], k34 = kernel[3][4], k40 = kernel[4][0], k41 = kernel[4][1], k42 = kernel[4][2], k43 = kernel[4][3], k44 = kernel[4][4], - + p00, p01, p02, p03, p04, p10, p11, p12, p13, p14, p20, p21, p22, p23, p24, p30, p31, p32, p33, p34, p40, p41, p42, p43, p44; - + for (y=0;y= width-1) pyn = pyc; if (y < 2) pypp = pyp; if (y >= width-2) pynn = pyn; - + for (x=0;x= width-1) pxn = pxc; if (x < 2) pxpp = pxp; if (x >= width-2) pxnn = pxn; - + p00 = pypp + pxpp; p01 = pypp + pxp; p02 = pypp + pxc; p03 = pypp + pxn; p04 = pypp + pxnn; p10 = pyp + pxpp; p11 = pyp + pxp; p12 = pyp + pxc; p13 = pyp + pxn; p14 = pyp + pxnn; p20 = pyc + pxpp; p21 = pyc + pxp; p22 = pyc + pxc; p23 = pyc + pxn; p24 = pyc + pxnn; @@ -440,13 +440,13 @@ Pixastic.Effects = (function() { + inData[p20] * k20 + inData[p21] * k21 + inData[p22] * k22 + inData[p23] * k24 + inData[p22] * k24 + inData[p30] * k30 + inData[p31] * k31 + inData[p32] * k32 + inData[p33] * k34 + inData[p32] * k34 + inData[p40] * k40 + inData[p41] * k41 + inData[p42] * k42 + inData[p43] * k44 + inData[p42] * k44; - + g = inData[p00+1] * k00 + inData[p01+1] * k01 + inData[p02+1] * k02 + inData[p03+1] * k04 + inData[p02+1] * k04 + inData[p10+1] * k10 + inData[p11+1] * k11 + inData[p12+1] * k12 + inData[p13+1] * k14 + inData[p12+1] * k14 + inData[p20+1] * k20 + inData[p21+1] * k21 + inData[p22+1] * k22 + inData[p23+1] * k24 + inData[p22+1] * k24 + inData[p30+1] * k30 + inData[p31+1] * k31 + inData[p32+1] * k32 + inData[p33+1] * k34 + inData[p32+1] * k34 + inData[p40+1] * k40 + inData[p41+1] * k41 + inData[p42+1] * k42 + inData[p43+1] * k44 + inData[p42+1] * k44; - + b = inData[p00+2] * k00 + inData[p01+2] * k01 + inData[p02+2] * k02 + inData[p03+2] * k04 + inData[p02+2] * k04 + inData[p10+2] * k10 + inData[p11+2] * k11 + inData[p12+2] * k12 + inData[p13+2] * k14 + inData[p12+2] * k14 + inData[p20+2] * k20 + inData[p21+2] * k21 + inData[p22+2] * k22 + inData[p23+2] * k24 + inData[p22+2] * k24 @@ -466,18 +466,18 @@ Pixastic.Effects = (function() { if (mono) { r = g = b = (r + g + b) / 3; } - + if (invert) { r = 255 - r; g = 255 - g; b = 255 - b; } - + outData[idx] = r; outData[idx+1] = g; outData[idx+2] = b; outData[idx+3] = a; - + if (progress) { prog = (idx/n*100 >> 0) / 100; if (prog > lastProg) { @@ -487,11 +487,11 @@ Pixastic.Effects = (function() { } } } - + function gaussian(inData, outData, width, height, kernelSize, progress) { var r, g, b, a, idx, n = width * height * 4, - x, y, i, j, + x, y, i, j, inx, iny, w, tmpData = [], maxKernelSize = 13, @@ -501,12 +501,12 @@ Pixastic.Effects = (function() { weights, kernels = [[1]], prog, lastProg = 0; - - + + for (i=1;i= width) { inx = width - 1; } - + idx = (iny * width + inx) * 4; r += inData[idx] * w; @@ -548,14 +548,14 @@ Pixastic.Effects = (function() { a += inData[idx + 3] * w; } - + idx = (y * width + x) * 4; - + tmpData[idx] = r; tmpData[idx+1] = g; tmpData[idx+2] = b; tmpData[idx+3] = a; - + if (progress) { prog = (idx/n*50 >> 0) / 100; if (prog > lastProg) { @@ -564,9 +564,9 @@ Pixastic.Effects = (function() { } } } - + lastProg = 0; - + // pass 2 for (y=0;y= height) { iny = height - 1; } - + idx = (iny * width + inx) * 4; - + r += tmpData[idx] * w; g += tmpData[idx + 1] * w; b += tmpData[idx + 2] * w; a += tmpData[idx + 3] * w; } - + idx = (y * width + x) * 4; - + outData[idx] = r; outData[idx+1] = g; outData[idx+2] = b; outData[idx+3] = a; - + if (progress) { prog = 0.5 + (idx/n*50 >> 0) / 100; if (prog > lastProg) { @@ -608,8 +608,8 @@ Pixastic.Effects = (function() { } } } - - + + return { invert : function(inData, outData, width, height, options, progress) { @@ -622,7 +622,7 @@ Pixastic.Effects = (function() { outData[i+2] = 255 - inData[i+2]; outData[i+3] = inData[i+3]; - + if (progress) { prog = (i/n*100 >> 0) / 100; if (prog > lastProg) { @@ -631,7 +631,7 @@ Pixastic.Effects = (function() { } } }, - + sepia : function(inData, outData, width, height, options, progress) { var n = width * height * 4, prog, lastProg = 0, @@ -645,7 +645,7 @@ Pixastic.Effects = (function() { outData[i+1] = (r * 0.349 + g * 0.686 + b * 0.168); outData[i+2] = (r * 0.272 + g * 0.534 + b * 0.131); outData[i+3] = inData[i+3]; - + if (progress) { prog = (i/n*100 >> 0) / 100; if (prog > lastProg) { @@ -654,7 +654,7 @@ Pixastic.Effects = (function() { } } }, - + solarize : function(inData, outData, width, height, options, progress) { var n = width * height * 4, prog, lastProg = 0, @@ -664,12 +664,12 @@ Pixastic.Effects = (function() { r = inData[i]; g = inData[i+1]; b = inData[i+2]; - + outData[i] = r > 127 ? 255 - r : r; outData[i+1] = g > 127 ? 255 - g : g; outData[i+2] = b > 127 ? 255 - b : b; outData[i+3] = inData[i+3]; - + if (progress) { prog = (i/n*100 >> 0) / 100; if (prog > lastProg) { @@ -684,7 +684,7 @@ Pixastic.Effects = (function() { brightness : 0, contrast : 0 }); - + var contrast = clamp(options.contrast, -1, 1) / 2, brightness = 1 + clamp(options.brightness, -1, 1), prog, lastProg = 0, @@ -701,16 +701,16 @@ Pixastic.Effects = (function() { r = inData[i]; g = inData[i+1]; b = inData[i+2]; - + r = (r + r * brightMul + brightAdd) * contrast + contrastAdd; g = (g + g * brightMul + brightAdd) * contrast + contrastAdd; b = (b + b * brightMul + brightAdd) * contrast + contrastAdd; - + outData[i] = r; outData[i+1] = g; outData[i+2] = b; outData[i+3] = inData[i+3]; - + if (progress) { prog = (i/n*100 >> 0) / 100; if (prog > lastProg) { @@ -719,7 +719,7 @@ Pixastic.Effects = (function() { } } }, - + desaturate : function(inData, outData, width, height, options, progress) { var n = width * height * 4, prog, lastProg = 0, @@ -731,7 +731,7 @@ Pixastic.Effects = (function() { outData[i+1] = level; outData[i+2] = level; outData[i+3] = inData[i+3]; - + if (progress) { prog = (i/n*100 >> 0) / 100; if (prog > lastProg) { @@ -740,7 +740,7 @@ Pixastic.Effects = (function() { } } }, - + lighten : function(inData, outData, width, height, options, progress) { var n = width * height * 4, prog, lastProg = 0, @@ -751,7 +751,7 @@ Pixastic.Effects = (function() { outData[i+1] = inData[i+1] * mul; outData[i+2] = inData[i+2] * mul; outData[i+3] = inData[i+3]; - + if (progress) { prog = (i/n*100 >> 0) / 100; if (prog > lastProg) { @@ -760,7 +760,7 @@ Pixastic.Effects = (function() { } } }, - + noise : function(inData, outData, width, height, options, progress) { var n = width * height * 4, prog, lastProg = 0, @@ -769,14 +769,14 @@ Pixastic.Effects = (function() { mono = !!options.mono, random = Math.random, rnd, r, g, b; - + for (var i=0;i> 0) / 100; if (prog > lastProg) { @@ -803,7 +803,7 @@ Pixastic.Effects = (function() { } } }, - + flipv : function(inData, outData, width, height, options, progress) { var inPix, outPix, n = width * height * 4, @@ -813,12 +813,12 @@ Pixastic.Effects = (function() { for (x=0;x> 0) / 100; if (prog > lastProg) { @@ -828,7 +828,7 @@ Pixastic.Effects = (function() { } } }, - + fliph : function(inData, outData, width, height, options, progress) { var inPix, outPix, n = width * height * 4, @@ -838,12 +838,12 @@ Pixastic.Effects = (function() { for (x=0;x> 0) / 100; if (prog > lastProg) { @@ -872,9 +872,9 @@ Pixastic.Effects = (function() { return p; } } - + gaussian(inData, tmpData, width, height, options.kernelSize, gaussProgress); - + for (i=0;i> 0) / 100 * 0.2; if (prog > lastProg) { @@ -899,16 +899,16 @@ Pixastic.Effects = (function() { convolve3x3 : function(inData, outData, width, height, options, progress) { convolve3x3(inData, outData, width, height, options.kernel, progress); }, - + convolve5x5 : function(inData, outData, width, height, options, progress) { convolve5x5(inData, outData, width, height, options.kernel, progress); }, - + // A 3x3 high-pass filter sharpen3x3 : function(inData, outData, width, height, options, progress) { var a = - clamp(options.strength, 0, 1); convolve3x3( - inData, outData, width, height, + inData, outData, width, height, [[a, a, a], [a, 1-a*8, a], [a, a, a]], @@ -920,7 +920,7 @@ Pixastic.Effects = (function() { sharpen5x5 : function(inData, outData, width, height, options, progress) { var a = - clamp(options.strength, 0, 1); convolve5x5( - inData, outData, width, height, + inData, outData, width, height, [[a, a, a, a, a], [a, a, a, a, a], [a, a, 1-a*24, a, a], @@ -934,19 +934,19 @@ Pixastic.Effects = (function() { soften3x3 : function(inData, outData, width, height, options, progress) { var c = 1/9; convolve3x3( - inData, outData, width, height, + inData, outData, width, height, [[c, c, c], [c, c, c], [c, c, c]], progress ); }, - + // A 5x5 low-pass mean filter soften5x5 : function(inData, outData, width, height, options, progress) { var c = 1/25; convolve5x5( - inData, outData, width, height, + inData, outData, width, height, [[c, c, c, c, c], [c, c, c, c, c], [c, c, c, c, c], @@ -955,12 +955,12 @@ Pixastic.Effects = (function() { progress ); }, - + // A 3x3 Cross edge-detect crossedges : function(inData, outData, width, height, options, progress) { var a = clamp(options.strength, 0, 1) * 5; convolve3x3( - inData, outData, width, height, + inData, outData, width, height, [[ 0, -a, 0], [-a, 0, a], [ 0, a, 0]], @@ -968,7 +968,7 @@ Pixastic.Effects = (function() { false, true ); }, - + // 3x3 directional emboss emboss : function(inData, outData, width, height, options, progress) { var amount = options.amount, @@ -976,7 +976,7 @@ Pixastic.Effects = (function() { x = Math.cos(-angle) * amount, y = Math.sin(-angle) * amount, n = width * height * 4, - + a00 = -x - y, a10 = -x, a20 = y - x, @@ -987,30 +987,30 @@ Pixastic.Effects = (function() { a22 = y + x, tmpData = [], - + prog, lastProg = 0, convProgress; - + if (progress) { convProgress = function(p) { progress(p * 0.5); return p; }; } - + convolve3x3( - inData, tmpData, width, height, + inData, tmpData, width, height, [[a00, a01, a02], [a10, 0, a12], [a20, a21, a22]] ); - + for (var i=0;i> 0) / 100 * 0.5; if (prog > lastProg) { @@ -1020,12 +1020,12 @@ Pixastic.Effects = (function() { } }, - + // A 3x3 Sobel edge detect (similar to Photoshop's) findedges : function(inData, outData, width, height, options, progress) { var n = width * height * 4, i, - data1 = [], + data1 = [], data2 = [], gr1, gr2, gg1, gg2, gb1, gb2, prog, lastProg = 0, @@ -1041,18 +1041,18 @@ Pixastic.Effects = (function() { return p; }; } - - convolve3x3(inData, data1, width, height, + + convolve3x3(inData, data1, width, height, [[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]] ); - convolve3x3(inData, data2, width, height, + convolve3x3(inData, data2, width, height, [[-1, -2, -1], [ 0, 0, 0], [ 1, 2, 1]] ); - + for (i=0;i> 0) / 100 * 0.2; if (prog > lastProg) { @@ -1081,22 +1081,22 @@ Pixastic.Effects = (function() { } } }, - + // A 3x3 edge enhance edgeenhance3x3 : function(inData, outData, width, height, options, progress) { convolve3x3( - inData, outData, width, height, + inData, outData, width, height, [[-1/9, -1/9, -1/9], [-1/9, 17/9, -1/9], [-1/9, -1/9, -1/9]], progress ); }, - + // A 5x5 edge enhance edgeenhance5x5 : function(inData, outData, width, height, options, progress) { convolve5x5( - inData, outData, width, height, + inData, outData, width, height, [[-1/25, -1/25, -1/25, -1/25, -1/25], [-1/25, -1/25, -1/25, -1/25, -1/25], [-1/25, -1/25, 49/25, -1/25, -1/25], @@ -1109,7 +1109,7 @@ Pixastic.Effects = (function() { // A 3x3 Laplacian edge-detect laplace3x3 : function(inData, outData, width, height, options, progress) { convolve3x3( - inData, outData, width, height, + inData, outData, width, height, [[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], @@ -1117,11 +1117,11 @@ Pixastic.Effects = (function() { false, true, true ); }, - + // A 5x5 Laplacian edge-detect laplace5x5 : function(inData, outData, width, height, options, progress) { convolve5x5( - inData, outData, width, height, + inData, outData, width, height, [[-1, -1, -1, -1, -1], [-1, -1, -1, -1, -1], [-1, -1, 24, -1, -1], @@ -1131,7 +1131,7 @@ Pixastic.Effects = (function() { false, true, true ); }, - + coloradjust : function(inData, outData, width, height, options, progress) { var n = width * height * 4, r, g, b, @@ -1154,7 +1154,7 @@ Pixastic.Effects = (function() { outData[i+1] = g; outData[i+2] = b; outData[i+3] = inData[i+3]; - + if (progress) { prog = (i/n*100 >> 0) / 100; if (prog > lastProg) { @@ -1163,7 +1163,7 @@ Pixastic.Effects = (function() { } } }, - + colorfilter : function(inData, outData, width, height, options, progress) { var n = width * height * 4, i, r, g, b, @@ -1173,14 +1173,14 @@ Pixastic.Effects = (function() { ar = clamp(options.r, 0, 1), ag = clamp(options.g, 0, 1), ab = clamp(options.b, 0, 1); - + for (i=0;i> 0; tmp = chroma * (h - h1); r = g = b = l - (r * 0.3 + g * 0.59 + b * 0.11); - + if (h1 == 0) { - r += chroma; + r += chroma; g += tmp; } else if (h1 == 1) { r += chroma - tmp; @@ -1230,7 +1230,7 @@ Pixastic.Effects = (function() { outData[i+1] = g * 255; outData[i+2] = b * 255; outData[i+3] = inData[i+3]; - + if (progress) { prog = (i/n*100 >> 0) / 100; if (prog > lastProg) { @@ -1239,7 +1239,7 @@ Pixastic.Effects = (function() { } } }, - + hsl : function(inData, outData, width, height, options, progress) { var n = width * height * 4, hue = clamp(options.hue, -1, 1), @@ -1252,15 +1252,15 @@ Pixastic.Effects = (function() { prog, lastProg = 0; hue = (hue * 6) % 6; - + for (var i=0;i 0 && vm > 0) { if (l <= 0.5) { s = vm / (vs+ms) * satMul; @@ -1307,7 +1307,7 @@ Pixastic.Effects = (function() { sextant = h >> 0; vmh = (v - m) * (h - sextant); if (sextant == 0) { - r = v; + r = v; g = m + vmh; b = m; } else if (sextant == 1) { @@ -1331,29 +1331,29 @@ Pixastic.Effects = (function() { g = m; b = v - vmh; } - + r *= 255; g *= 255; b *= 255; } } - + r = r * lightMul + lightAdd; g = g * lightMul + lightAdd; b = b * lightMul + lightAdd; - + if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; - + outData[i] = r; outData[i+1] = g; outData[i+2] = b; outData[i+3] = inData[i+3]; - + if (progress) { prog = (i/n*100 >> 0) / 100; if (prog > lastProg) { @@ -1362,7 +1362,7 @@ Pixastic.Effects = (function() { } } }, - + posterize : function(inData, outData, width, height, options, progress) { var numLevels = clamp(options.levels, 2, 256), numAreas = 256 / numLevels, @@ -1372,11 +1372,11 @@ Pixastic.Effects = (function() { prog, lastProg = 0; for (i=0;i>0); - outData[i+1] = numValues * ((inData[i+1] / numAreas)>>0); - outData[i+2] = numValues * ((inData[i+2] / numAreas)>>0); - + outData[i+1] = numValues * ((inData[i+1] / numAreas)>>0); + outData[i+2] = numValues * ((inData[i+2] / numAreas)>>0); + outData[i+3] = inData[i+3]; if (progress) { @@ -1386,18 +1386,18 @@ Pixastic.Effects = (function() { } } } - + }, - + removenoise : function(inData, outData, width, height, options, progress) { var r, g, b, c, y, x, idx, pyc, pyp, pyn, pxc, pxp, pxn, minR, minG, minB, maxR, maxG, maxB, n, prog, lastProg = 0; - + n = width * height * 4; - + for (y=0;y= width-1) pyn = pyc; - + for (x=0;x= width-1) pxn = pxc; - + minR = maxR = inData[pyc + pxp]; c = inData[pyc + pxn]; if (c < minR) minR = c; @@ -1434,7 +1434,7 @@ Pixastic.Effects = (function() { if (c < minG) minG = c; c = inData[pyn + pxc + 1]; if (c < minG) minG = c; - + minB = inData[pyc + pxp + 2]; c = inData[pyc + pxn + 2]; if (c < minB) minB = c; @@ -1446,19 +1446,19 @@ Pixastic.Effects = (function() { r = inData[idx]; g = inData[idx + 1]; b = inData[idx + 2]; - + if (r < minR) r = minR; if (r > maxR) r = maxR; if (g < minG) g = minG; if (g > maxG) g = maxG; if (b < minB) b = minB; if (b > maxB) b = maxB; - + outData[idx] = r; outData[idx+1] = g; outData[idx+2] = b; outData[idx+3] = inData[idx+3]; - + if (progress) { prog = (idx/n*100 >> 0) / 100; if (prog > lastProg) { @@ -1580,7 +1580,7 @@ Pixastic.Worker = function() { } Pixastic.Effects[e](inData.data, outData.data, width, height, options); - + me.onmessage({ data : { event : "progress", @@ -1588,7 +1588,7 @@ Pixastic.Worker = function() { } }); } - + me.onmessage({ data : { event : "done", @@ -1602,7 +1602,7 @@ Pixastic.Worker = function() { processMessage(data) }, 0); }; - + this.onmessage = function() {}; }; diff --git a/vendor/sindresorhus/screenfull.js b/public/sindresorhus/screenfull.js similarity index 100% rename from vendor/sindresorhus/screenfull.js rename to public/sindresorhus/screenfull.js diff --git a/stubs/OC/Hooks/Emitter.php b/stubs/OC/Hooks/Emitter.php new file mode 100644 index 0000000..dd9cf31 --- /dev/null +++ b/stubs/OC/Hooks/Emitter.php @@ -0,0 +1,51 @@ + + * @author Jörn Friedrich Dreyer + * @author Morris Jobke + * @author Robin Appelman + * + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ +namespace OC\Hooks; + +/** + * Class Emitter + * + * interface for all classes that are able to emit events + * + * @package OC\Hooks + * @deprecated 18.0.0 use events and the \OCP\EventDispatcher\IEventDispatcher service + */ +interface Emitter { + /** + * @param string $scope + * @param string $method + * @param callable $callback + * @return void + */ + public function listen($scope, $method, callable $callback); + + /** + * @param string $scope optional + * @param string $method optional + * @param callable $callback optional + * @return void + */ + public function removeListener($scope = null, $method = null, callable $callback = null); +} diff --git a/templates/cbreader.php b/templates/cbreader.php index 51cc42f..1f23288 100644 --- a/templates/cbreader.php +++ b/templates/cbreader.php @@ -1,30 +1,30 @@ getAppManager()->getAppVersion('epubreader') . '.' . $revision; +/** @var array $_ */ +/** @var OCP\IURLGenerator $urlGenerator */ +$urlGenerator = $_['urlGenerator']; +$downloadLink = $_['downloadLink']; +$fileId = $_['fileId']; +$fileName = $_['fileName']; +$fileType = $_['fileType']; +$scope = $_['scope']; +$cursor = $_['cursor']; +$defaults = $_['defaults']; +$preferences = $_['preferences']; +$metadata = $_['metadata']; +$annotations = $_['annotations']; +$title = htmlentities(basename($downloadLink)); +$revision = '0048'; +$version = \OC::$server->getAppManager()->getAppVersion('epubreader') . '.' . $revision; - /* Mobile safari, the new IE6 */ - $idevice = (strstr($_SERVER['HTTP_USER_AGENT'],'iPhone') - || strstr($_SERVER['HTTP_USER_AGENT'],'iPad') - || strstr($_SERVER['HTTP_USER_AGENT'],'iPod')); +/* Mobile safari, the new IE6 */ +$idevice = (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') + || strstr($_SERVER['HTTP_USER_AGENT'], 'iPad') + || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod')); - /* Owncloud currently does not implement CSPv3, remove this test when it does */ - $nonce = class_exists('\OC\Security\CSP\ContentSecurityPolicyNonceManager') - ? \OC::$server->getContentSecurityPolicyNonceManager()->getNonce() - : 'nonce_not_implemented'; +/* Owncloud currently does not implement CSPv3, remove this test when it does */ +$nonce = class_exists('\OC\Security\CSP\ContentSecurityPolicyNonceManager') + ? \OC::$server->getContentSecurityPolicyNonceManager()->getNonce() + : 'nonce_not_implemented'; ?> @@ -32,21 +32,21 @@ - + <?php p($title);?> - - - - - - - + + + + + + + - + diff --git a/templates/epubreader.php b/templates/epubreader.php index 3ce5bf0..68e5397 100644 --- a/templates/epubreader.php +++ b/templates/epubreader.php @@ -1,30 +1,30 @@ getAppManager()->getAppVersion('epubreader') . '.' . $revision; +/** @var array $_ */ +/** @var OCP\IURLGenerator $urlGenerator */ +$urlGenerator = $_['urlGenerator']; +$downloadLink = $_['downloadLink']; +$fileId = $_['fileId']; +$fileName = $_['fileName']; +$fileType = $_['fileType']; +$scope = $_['scope']; +$cursor = $_['cursor']; +$defaults = $_['defaults']; +$preferences = $_['preferences']; +$metadata = $_['metadata']; +$annotations = $_['annotations']; +$title = htmlentities(basename($downloadLink)); +$revision = '0072'; +$version = \OC::$server->getAppManager()->getAppVersion('epubreader') . '.' . $revision; - /* Mobile safari, the new IE6 */ - $idevice = (strstr($_SERVER['HTTP_USER_AGENT'],'iPhone') - || strstr($_SERVER['HTTP_USER_AGENT'],'iPad') - || strstr($_SERVER['HTTP_USER_AGENT'],'iPod')); +/* Mobile safari, the new IE6 */ +$idevice = (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') + || strstr($_SERVER['HTTP_USER_AGENT'], 'iPad') + || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod')); - /* Owncloud currently does not implement CSPv3, remove this test when it does */ - $nonce = class_exists('\OC\Security\CSP\ContentSecurityPolicyNonceManager') - ? \OC::$server->getContentSecurityPolicyNonceManager()->getNonce() - : 'nonce_not_implemented'; +/* Owncloud currently does not implement CSPv3, remove this test when it does */ +$nonce = class_exists('\OC\Security\CSP\ContentSecurityPolicyNonceManager') + ? \OC::$server->getContentSecurityPolicyNonceManager()->getNonce() + : 'nonce_not_implemented'; ?> @@ -32,31 +32,31 @@ - + <?php p($title);?> - - - - + + + + - - - - - - - - - + + + + + + + + + - - - + + + @@ -113,21 +113,21 @@
- +
- + %
- +
@@ -172,7 +172,7 @@ night
- t ('night mode can be toggled by clicking the book title')); ?>; + t('night mode can be toggled by clicking the book title')); ?>;
@@ -202,19 +202,19 @@
diff --git a/templates/pdfreader.php b/templates/pdfreader.php index 577de3c..32cfcb9 100644 --- a/templates/pdfreader.php +++ b/templates/pdfreader.php @@ -1,30 +1,30 @@ getAppManager()->getAppVersion('epubreader') . '.' . $revision; +/** @var array $_ */ +/** @var OCP\IURLGenerator $urlGenerator */ +$urlGenerator = $_['urlGenerator']; +$downloadLink = $_['downloadLink']; +$fileId = $_['fileId']; +$fileName = $_['fileName']; +$fileType = $_['fileType']; +$scope = $_['scope']; +$cursor = $_['cursor']; +$defaults = $_['defaults']; +$preferences = $_['preferences']; +$metadata = $_['metadata']; +$annotations = $_['annotations']; +$title = htmlentities(basename($downloadLink)); +$revision = '0130'; +$version = \OC::$server->getAppManager()->getAppVersion('epubreader') . '.' . $revision; - /* Mobile safari, the new IE6 */ - $idevice = (strstr($_SERVER['HTTP_USER_AGENT'],'iPhone') - || strstr($_SERVER['HTTP_USER_AGENT'],'iPad') - || strstr($_SERVER['HTTP_USER_AGENT'],'iPod')); +/* Mobile safari, the new IE6 */ +$idevice = (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') + || strstr($_SERVER['HTTP_USER_AGENT'], 'iPad') + || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod')); - /* Owncloud currently does not implement CSPv3, remove this test when it does */ - $nonce = class_exists('\OC\Security\CSP\ContentSecurityPolicyNonceManager') - ? \OC::$server->getContentSecurityPolicyNonceManager()->getNonce() - : 'nonce_not_implemented'; +/* Owncloud currently does not implement CSPv3, remove this test when it does */ +$nonce = class_exists('\OC\Security\CSP\ContentSecurityPolicyNonceManager') + ? \OC::$server->getContentSecurityPolicyNonceManager()->getNonce() + : 'nonce_not_implemented'; ?> @@ -32,43 +32,43 @@ - + <?php p($title);?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + diff --git a/templates/settings-personal.php b/templates/settings-personal.php index 36e8a7a..b17cf25 100644 --- a/templates/settings-personal.php +++ b/templates/settings-personal.php @@ -19,7 +19,9 @@ style('epubreader', 'settings');

/> + value="1" /> @@ -27,14 +29,18 @@ style('epubreader', 'settings');

/> + value="1" />

/> + value="1" />