Compare commits

..

60 Commits
v1.1 ... v1.6.1

Author SHA1 Message Date
carodej
181f090901 v1.6.1 2020-05-31 10:04:49 +02:00
carodej
252b6fd0bf v1.6 released 2020-05-28 13:00:54 +02:00
carodej
a76d1dec3b user management v1.6-alpha.1 2020-05-27 10:22:33 +02:00
carodej
143aca64dc Merge branch 'dev'
* dev:
  v1.5.2
2020-05-22 10:22:23 +02:00
carodej
3dc3f37cf6 v1.5.2 2020-05-22 10:20:55 +02:00
carodej
deff8d8741 Merge branch 'dev'
* dev:
  v1.5.1-beta.2
  v1.5.1-beta.1
2020-05-22 09:59:05 +02:00
carodej
beae4277ca v1.5.1-beta.2 2020-05-22 09:48:26 +02:00
carodej
be7d1bdc73 v1.5.1-beta.1 2020-05-22 09:40:34 +02:00
carodej
2eaf399441 Merge branch 'dev'
* dev:
  v1.5-beta.3
  v1.5-beta.2
  v1.5-beta.1
  v1.5-alpha.11
  v1.5-alpha.10
  v1.5-alpha.9
  v1.5-alpha.8
  v1.5-alpha.7
  v1.5-alpha.6
  v1.5-alpha.5
  v1.5-alpha.4
  v1.5-alpha.3
  v1.5-alpha.2
  v1.5-alpha.1
2020-05-19 17:52:07 +02:00
carodej
65f902fbcf v1.5-beta.3 2020-05-19 17:49:49 +02:00
carodej
5df0fa93b3 v1.5-beta.2 2020-05-19 11:27:47 +02:00
carodej
67b9416f64 v1.5-beta.1 2020-05-19 09:52:04 +02:00
carodej
8255597fd5 v1.5-alpha.11 2020-05-19 08:29:34 +02:00
carodej
633bef7660 v1.5-alpha.10 2020-05-18 12:37:33 +02:00
carodej
dfe4991177 v1.5-alpha.9 2020-05-18 09:32:34 +02:00
carodej
8daa05f710 v1.5-alpha.8 2020-05-16 17:52:24 +02:00
carodej
62434bcedb v1.5-alpha.7 2020-05-16 17:35:50 +02:00
carodej
6272f62e85 v1.5-alpha.6 2020-05-16 17:22:45 +02:00
carodej
4c8028696f v1.5-alpha.5 2020-05-16 17:12:38 +02:00
carodej
355f6a96ff v1.5-alpha.4 2020-05-16 12:18:37 +02:00
carodej
bdcfc26af7 v1.5-alpha.3 2020-05-16 12:11:17 +02:00
carodej
d2c4f2aa23 v1.5-alpha.2 2020-05-16 12:04:28 +02:00
carodej
41656235fc v1.5-alpha.1 2020-05-15 17:31:25 +02:00
carodej
26e79e7baa Merge branch 'dev'
* dev:
  set default storage as local
  v1.4.2 update
2020-05-06 07:44:11 +02:00
carodej
cfecf542ca set default storage as local 2020-05-06 07:42:37 +02:00
carodej
edd0b5195d v1.4.2 update 2020-05-06 07:41:36 +02:00
carodej
232d560cc4 Merge branch 'dev'
* dev:
  v1.4.1 update
  v1.4.1 update
2020-05-04 11:54:47 +02:00
carodej
b8b56584bd v1.4.1 update 2020-05-04 11:52:12 +02:00
carodej
ce2daaf6c4 v1.4.1 update 2020-05-04 11:45:13 +02:00
Peter Papp
78d9e0bd2a Update vuefilemanager.php 2020-05-04 11:15:11 +02:00
Peter Papp
55695ba06c Update README.md 2020-05-01 11:54:18 +02:00
carodej
ca3514d1d2 Merge branch 'dev'
* dev:
  v1.4
  vuefilemanager v1.4-beta.1
  vuefilemanager v1.4-alpha.2
  vuefilemanager v1.5-alpha.1
  editing with shared items in public
  backend update
  backend refactoring
  protected sharing update
  vuex refactoring
  frontend/backend update
  vue frontend update
  vue frontend update
  vue router implemented
  implementing vue router
2020-05-01 11:21:20 +02:00
carodej
b2db3755d8 v1.4 2020-05-01 11:04:03 +02:00
carodej
606c1895a9 vuefilemanager v1.4-beta.1 2020-04-30 10:55:36 +02:00
carodej
968b12c4ac vuefilemanager v1.4-alpha.2 2020-04-29 16:32:40 +02:00
carodej
0f3cbaec3d vuefilemanager v1.5-alpha.1 2020-04-29 11:32:08 +02:00
carodej
2614efe601 editing with shared items in public 2020-04-28 18:06:38 +02:00
carodej
eb6bd646c8 backend update 2020-04-27 12:38:08 +02:00
carodej
65147870fd backend refactoring 2020-04-27 08:34:09 +02:00
carodej
586f0bba68 protected sharing update 2020-04-24 12:50:11 +02:00
carodej
c4b26d70b5 vuex refactoring 2020-04-23 17:57:55 +02:00
carodej
8cbc58f775 frontend/backend update 2020-04-23 12:40:22 +02:00
carodej
8740cc7685 vue frontend update 2020-04-20 09:01:54 +02:00
carodej
506c39896a vue frontend update 2020-04-17 11:33:06 +02:00
carodej
9db34fd90e file delete bugfixes 2020-04-08 09:37:54 +02:00
carodej
ae4353cc4b vue router implemented 2020-04-07 14:48:29 +02:00
carodej
bde58fbf60 implementing vue router 2020-04-06 20:45:56 +02:00
carodej
01b399e4a6 fixed - Cannot read property '$t' 2020-04-06 19:56:56 +02:00
carodej
6235ffd0dc deleted file 2020-04-05 12:19:21 +02:00
MakingCG
4504276563 Version 1.3
- i18n localization support
- Added SK, EN language files
- Video/Audio preview in file preview panel (Thanks to Joshua Fouyon to participating on this feature)
- Drop uploading (You can now drag files from desktop and drop it to VueFileManager)
- Fixed bug when rename item in safari browser
- Fixed bug when you drag folder from trash to favourites in sidebar panel
- small functions and design improvements
2020-04-03 11:52:54 +02:00
MakingCG
96da39923d Update app.php 2020-04-01 18:47:37 +02:00
MakingCG
8633650f82 Added i18n support 2020-04-01 18:44:47 +02:00
MakingCG
182091c21a bugfixes 2020-03-29 11:42:32 +02:00
MakingCG
7bed9ad7b8 bug fixes 2020-03-28 19:30:04 +01:00
MakingCG
7eb4238efd bug fixes 2020-03-28 19:17:58 +01:00
MakingCG
ea74c8885f Version 1.2
- Move your items by folder tree
- Fixed bug with image rotation on iOS Device
2020-03-28 12:26:51 +01:00
MakingCG
7cdf463e4e bug fixes 2020-03-16 18:23:22 +01:00
MakingCG
850f910b96 Update Readme.md 2020-03-15 11:11:21 +01:00
MakingCG
4492696e3d readme 2020-03-15 11:09:42 +01:00
MakingCG
dc74020f2d Config update 2020-03-15 10:55:32 +01:00
231 changed files with 40657 additions and 7924 deletions

View File

@@ -5,6 +5,8 @@ APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
SCOUT_DRIVER=tntsearch
FILESYSTEM_DRIVER=local
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
@@ -37,10 +39,16 @@ AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
DO_SPACES_KEY=
DO_SPACES_SECRET=
DO_SPACES_ENDPOINT=
DO_SPACES_REGION=
DO_SPACES_BUCKET=
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
PASSPORT_CLIENT_ID=
PASSPORT_CLIENT_SECRET=
APP_DEPLOY_SECRET=

6
.idea/misc.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/vue-filemanager-laravel.iml" filepath="$PROJECT_DIR$/.idea/vue-filemanager-laravel.iml" />
</modules>
</component>
</project>

128
.idea/php.xml generated
View File

@@ -1,128 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpIncludePathManager">
<include_path>
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
<path value="$PROJECT_DIR$/vendor/gabrielelana/byte-units" />
<path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
<path value="$PROJECT_DIR$/vendor/asm89/stack-cors" />
<path value="$PROJECT_DIR$/vendor/psy/psysh" />
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
<path value="$PROJECT_DIR$/vendor/mockery/mockery" />
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
<path value="$PROJECT_DIR$/vendor/nesbot/carbon" />
<path value="$PROJECT_DIR$/vendor/intervention/image" />
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
<path value="$PROJECT_DIR$/vendor/monolog/monolog" />
<path value="$PROJECT_DIR$/vendor/phpoption/phpoption" />
<path value="$PROJECT_DIR$/vendor/barryvdh/laravel-cors" />
<path value="$PROJECT_DIR$/vendor/opis/closure" />
<path value="$PROJECT_DIR$/vendor/paragonie/random_compat" />
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
<path value="$PROJECT_DIR$/vendor/egulias/email-validator" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
<path value="$PROJECT_DIR$/vendor/teamtnt/laravel-scout-tntsearch-driver" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
<path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
<path value="$PROJECT_DIR$/vendor/teamtnt/tntsearch" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
<path value="$PROJECT_DIR$/vendor/composer" />
<path value="$PROJECT_DIR$/vendor/fideloper/proxy" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-token-stream" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-ctype" />
<path value="$PROJECT_DIR$/vendor/symfony/translation" />
<path value="$PROJECT_DIR$/vendor/dnoegel/php-xdg-base-dir" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" />
<path value="$PROJECT_DIR$/vendor/ramsey/uuid" />
<path value="$PROJECT_DIR$/vendor/symfony/finder" />
<path value="$PROJECT_DIR$/vendor/symfony/routing" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/league/flysystem" />
<path value="$PROJECT_DIR$/vendor/symfony/css-selector" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php72" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php73" />
<path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
<path value="$PROJECT_DIR$/vendor/symfony/debug" />
<path value="$PROJECT_DIR$/vendor/erusev/parsedown" />
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/mime" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-iconv" />
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" />
<path value="$PROJECT_DIR$/vendor/symfony/console" />
<path value="$PROJECT_DIR$/vendor/symfony/process" />
<path value="$PROJECT_DIR$/vendor/swiftmailer/swiftmailer" />
<path value="$PROJECT_DIR$/vendor/fzaninotto/faker" />
<path value="$PROJECT_DIR$/vendor/phpspec/prophecy" />
<path value="$PROJECT_DIR$/vendor/askedio/laravel-soft-cascade" />
<path value="$PROJECT_DIR$/vendor/laravel/framework" />
<path value="$PROJECT_DIR$/vendor/laravel/scout" />
<path value="$PROJECT_DIR$/vendor/laravel/tinker" />
<path value="$PROJECT_DIR$/vendor/hamcrest/hamcrest-php" />
<path value="$PROJECT_DIR$/vendor/dragonmantank/cron-expression" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
<path value="$PROJECT_DIR$/vendor/beyondcode/laravel-dump-server" />
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
<path value="$PROJECT_DIR$/vendor/nunomaduro/collision" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-docblock" />
<path value="$PROJECT_DIR$/vendor/tijsverkoyen/css-to-inline-styles" />
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
<path value="$PROJECT_DIR$/vendor/sebastian/resource-operations" />
<path value="$PROJECT_DIR$/vendor/vlucas/phpdotenv" />
<path value="$PROJECT_DIR$/vendor/sebastian/version" />
<path value="$PROJECT_DIR$/vendor/filp/whoops" />
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
<path value="$PROJECT_DIR$/vendor/psr/http-message" />
<path value="$PROJECT_DIR$/vendor/jakub-onderka/php-console-color" />
<path value="$PROJECT_DIR$/vendor/psr/container" />
<path value="$PROJECT_DIR$/vendor/jakub-onderka/php-console-highlighter" />
<path value="$PROJECT_DIR$/vendor/psr/simple-cache" />
<path value="$PROJECT_DIR$/vendor/psr/log" />
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
<path value="$PROJECT_DIR$/vendor/ralouphie/getallheaders" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/psr7" />
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" />
<path value="$PROJECT_DIR$/vendor/psr/http-factory" />
<path value="$PROJECT_DIR$/vendor/laravel/passport" />
<path value="$PROJECT_DIR$/vendor/league/event" />
<path value="$PROJECT_DIR$/vendor/facade/ignition" />
<path value="$PROJECT_DIR$/vendor/league/oauth2-server" />
<path value="$PROJECT_DIR$/vendor/facade/flare-client-php" />
<path value="$PROJECT_DIR$/vendor/defuse/php-encryption" />
<path value="$PROJECT_DIR$/vendor/phpseclib/phpseclib" />
<path value="$PROJECT_DIR$/vendor/laminas/laminas-zendframework-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/error-handler" />
<path value="$PROJECT_DIR$/vendor/laminas/laminas-diactoros" />
<path value="$PROJECT_DIR$/vendor/firebase/php-jwt" />
<path value="$PROJECT_DIR$/vendor/fruitcake/laravel-cors" />
<path value="$PROJECT_DIR$/vendor/scrivo/highlight.php" />
<path value="$PROJECT_DIR$/vendor/sebastian/type" />
<path value="$PROJECT_DIR$/vendor/lcobucci/jwt" />
<path value="$PROJECT_DIR$/vendor/symfony/psr-http-message-bridge" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/guzzle" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/promises" />
<path value="$PROJECT_DIR$/vendor/facade/ignition-contracts" />
<path value="$PROJECT_DIR$/vendor/league/commonmark" />
<path value="$PROJECT_DIR$/vendor/php-http/message-factory" />
<path value="$PROJECT_DIR$/vendor/nyholm/psr7" />
</include_path>
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="7.2" />
<component name="PhpUnit">
<phpunit_settings>
<PhpUnitSettings load_method="CUSTOM_LOADER" configuration_file_path="$PROJECT_DIR$/phpunit.xml" custom_loader_path="$PROJECT_DIR$/vendor/autoload.php" use_configuration_file="true" />
</phpunit_settings>
</component>
</project>

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/app" isTestSource="false" packagePrefix="App\" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="Tests\" />
<excludeFolder url="file://$MODULE_DIR$/vendor/defuse/php-encryption" />
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/flare-client-php" />
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition" />
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/firebase/php-jwt" />
<excludeFolder url="file://$MODULE_DIR$/vendor/fruitcake/laravel-cors" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/guzzle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/promises" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laminas/laminas-diactoros" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laminas/laminas-zendframework-bridge" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/passport" />
<excludeFolder url="file://$MODULE_DIR$/vendor/lcobucci/jwt" />
<excludeFolder url="file://$MODULE_DIR$/vendor/league/commonmark" />
<excludeFolder url="file://$MODULE_DIR$/vendor/league/event" />
<excludeFolder url="file://$MODULE_DIR$/vendor/league/oauth2-server" />
<excludeFolder url="file://$MODULE_DIR$/vendor/nyholm/psr7" />
<excludeFolder url="file://$MODULE_DIR$/vendor/php-http/message-factory" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpseclib/phpseclib" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-factory" />
<excludeFolder url="file://$MODULE_DIR$/vendor/scrivo/highlight.php" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/type" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/error-handler" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/psr-http-message-bridge" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectTasksOptions" suppressed-tasks="SCSS" />
</project>

739
.idea/workspace.xml generated
View File

@@ -1,739 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="6ba7f65e-b845-4413-bbbb-cad4b4fb5f38" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/.editorconfig" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/php.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/php.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/vue-filemanager-laravel.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/vue-filemanager-laravel.iml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/FileManagerFile.php" beforeDir="false" afterPath="$PROJECT_DIR$/app/FileManagerFile.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/FileManagerFolder.php" beforeDir="false" afterPath="$PROJECT_DIR$/app/FileManagerFolder.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/Http/Controllers/FileManagerController.php" beforeDir="false" afterPath="$PROJECT_DIR$/app/Http/Controllers/FileManagerController.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/composer.lock" beforeDir="false" afterPath="$PROJECT_DIR$/composer.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config/vuefilemanager.php" beforeDir="false" afterPath="$PROJECT_DIR$/config/vuefilemanager.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/public/css/app.css" beforeDir="false" afterPath="$PROJECT_DIR$/public/css/app.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/public/js/main.js" beforeDir="false" afterPath="$PROJECT_DIR$/public/js/main.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/public/mix-manifest.json" beforeDir="false" afterPath="$PROJECT_DIR$/public/mix-manifest.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManager.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManager.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Auth.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Auth.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/Alert.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/Alert.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/ContextMenu.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/ContextMenu.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/DesktopToolbar.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/DesktopToolbar.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/FileInfoPanel.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/FileInfoPanel.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/FileItemList.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/FileItemList.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/FilesContainer.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/FilesContainer.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/MobileActionButton.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/MobileActionButton.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/MobileActionButtonUpload.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/MobileActionButtonUpload.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/MobileOptionList.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/MobileOptionList.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/MobileToolbar.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/MobileToolbar.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/ToolbarButton.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/ToolbarButton.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/ToolbarButtonUpload.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/ToolbarButtonUpload.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Others/PageHeader.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Others/PageHeader.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Others/TextLabel.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Others/TextLabel.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Sidebar.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Sidebar.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Sidebar/StorageSize.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Sidebar/StorageSize.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Sidebar/UserHeadline.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Sidebar/UserHeadline.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/UserSettings.vue" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/UserSettings.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/components/router.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/helpers.js" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/helpers.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/store/modules/filesView.js" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/store/modules/filesView.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/js/store/modules/userAuth.js" beforeDir="false" afterPath="$PROJECT_DIR$/resources/js/store/modules/userAuth.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/sass/vue-file-manager/_forms.scss" beforeDir="false" afterPath="$PROJECT_DIR$/resources/sass/vue-file-manager/_forms.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/resources/views/index.blade.php" beforeDir="false" afterPath="$PROJECT_DIR$/resources/views/index.blade.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/routes/api.php" beforeDir="false" afterPath="$PROJECT_DIR$/routes/api.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/webpack.mix.js" beforeDir="false" afterPath="$PROJECT_DIR$/webpack.mix.js" afterDir="false" />
</list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ComposerSettings" doNotAsk="true" synchronizationState="SYNCHRONIZE">
<pharConfigPath>$PROJECT_DIR$/composer.json</pharConfigPath>
<execution>
<executable />
</execution>
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Auth.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="201">
<caret line="516" column="13" selection-start-line="516" selection-start-column="13" selection-end-line="516" selection-end-column="13" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/resources/sass/vue-file-manager/_forms.scss">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="112">
<caret line="28" column="26" lean-forward="true" selection-start-line="28" selection-start-column="26" selection-end-line="28" selection-end-column="26" />
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="FindInProjectRecents">
<findStrings>
<find>SET_AUTHORIZED</find>
<find>error.data</find>
<find>SET_START_DIREC</find>
<find>Nunito:400</find>
<find>context</find>
<find>token</find>
<find>cookie</find>
<find>getAppData</find>
<find>SET_AUT</find>
<find>PublicCloud</find>
<find>Illuminate\Http\Response</find>
<find>$updateText</find>
<find>...map</find>
<find>...mapGetters</find>
<find>access_token</find>
<find>user_account_capacity</find>
<find>'bo</find>
<find>SET_CURRENT</find>
<find>logOut</find>
<find>255</find>
<find>_forms</find>
<find>limit</find>
<find>max_file_uploads</find>
<find>post_max_size</find>
<find>uploadFiles</find>
<find>whereIn</find>
<find>trash</find>
<find>you exceed your storage</find>
<find>deleted_files</find>
<find>trashed_files</find>
</findStrings>
</component>
<component name="FrameworkCommandLineHistory">
<commandsHistory>
<command text="npm update" />
<command text="npm run prod" />
<command text="npm update" />
<command text="npm run prod" />
<command text="npm update" />
<command text="npm run prod" />
<command text="npm remove sass-loader" />
<command text="npm update" />
<command text="npm rebuild" />
<command text="npm run prod" />
<command text="npm run hot" />
<command text="php artisan make:controller AppFunctionsController" />
<command text="php artisan dump-autoload" />
<command text="composer dump-autoload" />
<command text="php artisan serve" />
<command text="composer update" />
<command text="npm run prod" />
<command text="npm run hot" />
<command text="php artisan serve" />
<command text="npm run hot" />
<command text="php artisan serve" />
<command text="npm run hot" />
<command text="npm run prod" />
<command text="npm run hot" />
<command text="npm run prod" />
</commandsHistory>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="HighlightingSettingsPerFile">
<setting file="mock:///Dummy.txt" root0="SKIP_INSPECTION" />
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/package.json" />
<option value="$PROJECT_DIR$/app/Http/Middleware/Authenticate.php" />
<option value="$PROJECT_DIR$/resources/js/bootstrap.js" />
<option value="$PROJECT_DIR$/app/Http/Middleware/CookieAuth.php" />
<option value="$PROJECT_DIR$/app/Http/Kernel.php" />
<option value="$PROJECT_DIR$/app/Http/Middleware/EncryptCookies.php" />
<option value="$PROJECT_DIR$/app/Http/Controllers/PrivateCLoud/AuthController.php" />
<option value="$PROJECT_DIR$/resources/js/main.js" />
<option value="$PROJECT_DIR$/resources/js/store/modules/app.js" />
<option value="$PROJECT_DIR$/.gitignore" />
<option value="$PROJECT_DIR$/app/Http/Controllers/PrivateCLoud/FileManagerController.php" />
<option value="$PROJECT_DIR$/app/Http/Controllers/PrivateCLoud/UserAccountController.php" />
<option value="$PROJECT_DIR$/app/Http/Controllers/AppFunctionsController.php" />
<option value="$PROJECT_DIR$/resources/sass/app.scss" />
<option value="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Others/UserImageInput.vue" />
<option value="$PROJECT_DIR$/app/Http/Controllers/Auth/AuthController.php" />
<option value="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Sidebar/StorageSize.vue" />
<option value="$PROJECT_DIR$/app/Http/helpers.php" />
<option value="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Sidebar/UserHeadline.vue" />
<option value="$PROJECT_DIR$/app/Http/Controllers/UserAccountController.php" />
<option value="$PROJECT_DIR$/routes/web.php" />
<option value="$PROJECT_DIR$/resources/js/store/modules/userAuth.js" />
<option value="$PROJECT_DIR$/resources/js/App.vue" />
<option value="$PROJECT_DIR$/resources/js/components/VueFileManager.vue" />
<option value="$PROJECT_DIR$/.env" />
<option value="$USER_HOME$/Desktop/vue-file-manager-file-manager-127.0.0.111-03-2020" />
<option value="&lt;d768a9d2-ae0a-4b11-a436-c632a530c3ce&gt;/var/www/devvuefilemanagerlaravel.hi5ve.digital/.env" />
<option value="&lt;d768a9d2-ae0a-4b11-a436-c632a530c3ce&gt;/etc/apache2/sites-available/devvuefilemanager.hi5ve.digital.conf" />
<option value="&lt;d768a9d2-ae0a-4b11-a436-c632a530c3ce&gt;/var/www/devvuefilemanager.hi5ve.digital/.env" />
<option value="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/UserSettings.vue" />
<option value="$PROJECT_DIR$/app/FileManagerFile.php" />
<option value="$PROJECT_DIR$/routes/api.php" />
<option value="&lt;d768a9d2-ae0a-4b11-a436-c632a530c3ce&gt;/var/www/devvuefilemanager.hi5ve.digital/config/vuefilemanager.php" />
<option value="&lt;d768a9d2-ae0a-4b11-a436-c632a530c3ce&gt;/var/www/devvuefilemanager.hi5ve.digital/public/info.php" />
<option value="&lt;d768a9d2-ae0a-4b11-a436-c632a530c3ce&gt;/etc/php/7.3/apache2/php.ini" />
<option value="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Sidebar.vue" />
<option value="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/Alert.vue" />
<option value="$PROJECT_DIR$/app/Http/Controllers/FileManagerController.php" />
<option value="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/FileItemList.vue" />
<option value="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/ToolbarButtonUpload.vue" />
<option value="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Others/TextLabel.vue" />
<option value="$PROJECT_DIR$/resources/js/helpers.js" />
<option value="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView.vue" />
<option value="$PROJECT_DIR$/webpack.mix.js" />
<option value="$PROJECT_DIR$/public/mix-manifest.json" />
<option value="$PROJECT_DIR$/resources/views/index.blade.php" />
<option value="$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Auth.vue" />
<option value="$PROJECT_DIR$/resources/js/store/modules/filesView.js" />
<option value="$PROJECT_DIR$/app/FileManagerFolder.php" />
<option value="$PROJECT_DIR$/config/vuefilemanager.php" />
<option value="$PROJECT_DIR$/resources/sass/vue-file-manager/_forms.scss" />
</list>
</option>
</component>
<component name="PhpWorkspaceProjectConfiguration">
<include_path>
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
<path value="$PROJECT_DIR$/vendor/gabrielelana/byte-units" />
<path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
<path value="$PROJECT_DIR$/vendor/asm89/stack-cors" />
<path value="$PROJECT_DIR$/vendor/psy/psysh" />
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
<path value="$PROJECT_DIR$/vendor/mockery/mockery" />
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
<path value="$PROJECT_DIR$/vendor/nesbot/carbon" />
<path value="$PROJECT_DIR$/vendor/intervention/image" />
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
<path value="$PROJECT_DIR$/vendor/monolog/monolog" />
<path value="$PROJECT_DIR$/vendor/phpoption/phpoption" />
<path value="$PROJECT_DIR$/vendor/barryvdh/laravel-cors" />
<path value="$PROJECT_DIR$/vendor/opis/closure" />
<path value="$PROJECT_DIR$/vendor/paragonie/random_compat" />
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
<path value="$PROJECT_DIR$/vendor/egulias/email-validator" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
<path value="$PROJECT_DIR$/vendor/teamtnt/laravel-scout-tntsearch-driver" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
<path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
<path value="$PROJECT_DIR$/vendor/teamtnt/tntsearch" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
<path value="$PROJECT_DIR$/vendor/composer" />
<path value="$PROJECT_DIR$/vendor/fideloper/proxy" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-token-stream" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-ctype" />
<path value="$PROJECT_DIR$/vendor/symfony/translation" />
<path value="$PROJECT_DIR$/vendor/dnoegel/php-xdg-base-dir" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" />
<path value="$PROJECT_DIR$/vendor/ramsey/uuid" />
<path value="$PROJECT_DIR$/vendor/symfony/finder" />
<path value="$PROJECT_DIR$/vendor/symfony/routing" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/league/flysystem" />
<path value="$PROJECT_DIR$/vendor/symfony/css-selector" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php72" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php73" />
<path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
<path value="$PROJECT_DIR$/vendor/symfony/debug" />
<path value="$PROJECT_DIR$/vendor/erusev/parsedown" />
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/mime" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-iconv" />
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" />
<path value="$PROJECT_DIR$/vendor/symfony/console" />
<path value="$PROJECT_DIR$/vendor/symfony/process" />
<path value="$PROJECT_DIR$/vendor/swiftmailer/swiftmailer" />
<path value="$PROJECT_DIR$/vendor/fzaninotto/faker" />
<path value="$PROJECT_DIR$/vendor/phpspec/prophecy" />
<path value="$PROJECT_DIR$/vendor/askedio/laravel-soft-cascade" />
<path value="$PROJECT_DIR$/vendor/laravel/framework" />
<path value="$PROJECT_DIR$/vendor/laravel/scout" />
<path value="$PROJECT_DIR$/vendor/laravel/tinker" />
<path value="$PROJECT_DIR$/vendor/hamcrest/hamcrest-php" />
<path value="$PROJECT_DIR$/vendor/dragonmantank/cron-expression" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
<path value="$PROJECT_DIR$/vendor/beyondcode/laravel-dump-server" />
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
<path value="$PROJECT_DIR$/vendor/nunomaduro/collision" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-docblock" />
<path value="$PROJECT_DIR$/vendor/tijsverkoyen/css-to-inline-styles" />
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
<path value="$PROJECT_DIR$/vendor/sebastian/resource-operations" />
<path value="$PROJECT_DIR$/vendor/vlucas/phpdotenv" />
<path value="$PROJECT_DIR$/vendor/sebastian/version" />
<path value="$PROJECT_DIR$/vendor/filp/whoops" />
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
<path value="$PROJECT_DIR$/vendor/psr/http-message" />
<path value="$PROJECT_DIR$/vendor/jakub-onderka/php-console-color" />
<path value="$PROJECT_DIR$/vendor/psr/container" />
<path value="$PROJECT_DIR$/vendor/jakub-onderka/php-console-highlighter" />
<path value="$PROJECT_DIR$/vendor/psr/simple-cache" />
<path value="$PROJECT_DIR$/vendor/psr/log" />
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
<path value="$PROJECT_DIR$/vendor/ralouphie/getallheaders" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/psr7" />
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" />
<path value="$PROJECT_DIR$/vendor/psr/http-factory" />
<path value="$PROJECT_DIR$/vendor/laravel/passport" />
<path value="$PROJECT_DIR$/vendor/league/event" />
<path value="$PROJECT_DIR$/vendor/facade/ignition" />
<path value="$PROJECT_DIR$/vendor/league/oauth2-server" />
<path value="$PROJECT_DIR$/vendor/facade/flare-client-php" />
<path value="$PROJECT_DIR$/vendor/defuse/php-encryption" />
<path value="$PROJECT_DIR$/vendor/phpseclib/phpseclib" />
<path value="$PROJECT_DIR$/vendor/laminas/laminas-zendframework-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/error-handler" />
<path value="$PROJECT_DIR$/vendor/laminas/laminas-diactoros" />
<path value="$PROJECT_DIR$/vendor/firebase/php-jwt" />
<path value="$PROJECT_DIR$/vendor/fruitcake/laravel-cors" />
<path value="$PROJECT_DIR$/vendor/scrivo/highlight.php" />
<path value="$PROJECT_DIR$/vendor/sebastian/type" />
<path value="$PROJECT_DIR$/vendor/lcobucci/jwt" />
<path value="$PROJECT_DIR$/vendor/symfony/psr-http-message-bridge" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/guzzle" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/promises" />
<path value="$PROJECT_DIR$/vendor/facade/ignition-contracts" />
<path value="$PROJECT_DIR$/vendor/league/commonmark" />
<path value="$PROJECT_DIR$/vendor/php-http/message-factory" />
<path value="$PROJECT_DIR$/vendor/nyholm/psr7" />
</include_path>
</component>
<component name="ProjectFrameBounds" fullScreen="true">
<option name="width" value="1680" />
<option name="height" value="1050" />
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="true">
<ConfirmationsSetting value="2" id="Add" />
</component>
<component name="ProjectView">
<navigator proportions="" version="1">
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="ProjectPane">
<subPane>
<expand>
<path>
<item name="vue-filemanager-laravel-v1.1" type="b2602c69:ProjectViewProjectNode" />
<item name="vue-filemanager-laravel-v1.1" type="462c0819:PsiDirectoryNode" />
</path>
</expand>
<select />
</subPane>
</pane>
<pane id="Scope" />
</panes>
</component>
<component name="PropertiesComponent">
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
<property name="WebServerToolWindowFactoryState" value="true" />
<property name="WebServerToolWindowPanel.toolwindow.highlight.mappings" value="true" />
<property name="WebServerToolWindowPanel.toolwindow.highlight.symlinks" value="true" />
<property name="WebServerToolWindowPanel.toolwindow.show.date" value="false" />
<property name="WebServerToolWindowPanel.toolwindow.show.permissions" value="false" />
<property name="WebServerToolWindowPanel.toolwindow.show.size" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/resources/sass" />
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
<property name="nodejs_package_manager_path" value="npm" />
</component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/app/Http/Controllers" />
<recent name="$PROJECT_DIR$/resources/sass/vue-file-manager" />
<recent name="$PROJECT_DIR$/app/Http/Controllers/PrivateCLoud" />
</key>
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/resources/sass" />
<recent name="$PROJECT_DIR$/resources/js" />
<recent name="$PROJECT_DIR$/public/assets/images" />
<recent name="$PROJECT_DIR$/app/Http/Controllers/PublicCloud" />
<recent name="$PROJECT_DIR$/app" />
</key>
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager">
<configuration name="phpunit.xml" type="PHPUnitRunConfigurationType" factoryName="PHPUnit">
<TestRunner scope="XML" />
<method v="2" />
</configuration>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="6ba7f65e-b845-4413-bbbb-cad4b4fb5f38" name="Default Changelist" comment="" />
<created>1582538406416</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1582538406416</updated>
<workItem from="1582538408226" duration="28590000" />
<workItem from="1583169038847" duration="49277000" />
<workItem from="1583771973016" duration="47540000" />
<workItem from="1584014365621" duration="499000" />
<workItem from="1584201902438" duration="1297000" />
<workItem from="1584205890781" duration="1931000" />
</task>
<servers />
</component>
<component name="TimeTrackingManager">
<option name="totallyTimeSpent" value="129134000" />
</component>
<component name="ToolWindowManager">
<frame x="0" y="0" width="1680" height="1050" extended-state="0" />
<layout>
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.15654762" />
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
<window_info id="npm" order="2" side_tool="true" />
<window_info id="Favorites" order="3" side_tool="true" />
<window_info anchor="bottom" id="Message" order="0" />
<window_info anchor="bottom" id="Find" order="1" />
<window_info anchor="bottom" id="Run" order="2" weight="0.3295238" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
<window_info anchor="bottom" id="TODO" order="6" />
<window_info anchor="bottom" id="Docker" order="7" show_stripe_button="false" />
<window_info anchor="bottom" id="Version Control" order="8" />
<window_info anchor="bottom" id="Database Changes" order="9" />
<window_info active="true" anchor="bottom" id="Command Line Tools Console" order="10" visible="true" weight="0.36761904" />
<window_info anchor="bottom" id="Terminal" order="11" weight="0.3295238" />
<window_info anchor="bottom" id="Event Log" order="12" side_tool="true" />
<window_info anchor="bottom" id="File Transfer" order="13" weight="0.3295238" />
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
<window_info anchor="right" id="Database" order="3" />
<window_info anchor="right" id="Remote Host" order="4" weight="0.23869048" />
</layout>
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-RlTVKdTenHVQeDuC-8f8b71f93d874c58899eae34ff855b91.jpg.1280x0_q85.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-qu7zENEPpyXacK9u-8acb7489e4354e9fa12b786f4f1014b3.jpg.1280x0_q85.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-PwOYrH3X4Q5MFNnJ-b828ce5c1d014deab79c6b1ac8dd5500.jpg.1280x0_q85.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-PeK8nBe7vKFR2DXN-8480033d08b555735bcc1df441eeec0f.png">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-Ogjq9EIILgeojKDb-nf88xyvvCWOJHY93-kitchen-island.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-NfLjyaaboBPCGi3X-7bec4e11b047456780d83011701a662c.jpg.1280x0_q85.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-md1FYpic11mXzsMH-59352395_2290695347810363_751927439731487941_n.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-lnh7N5vgH74DhOOh-57bad2c20c758f20b83b2344212a2a93.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-ddGQjKsXe6smj3Jx-7bec4e11b047456780d83011701a662c.jpg.1280x0_q85.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-eIXPHBrXEjqxydte-d5410c8079e3a3970303779305d11048.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-Fg3cXWFgEn6Cmt5M-6f5362be8aca06dc4ea234865ac49736.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-fNx1iGh1lpGyS66P-af0c68fb4d3b82da011ca4b0c18c8a65.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-Gv6TX9lZl8TZ5kCK-8f8b71f93d874c58899eae34ff855b91.jpg.1280x0_q85.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-HlK34TY0sfw4lDk3-nf88xyvvCWOJHY93-kitchen-island.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-i2BdCpXqXyMcS5oB-ea7afab3993a45c3a88ee7eb9ce42a8e.jpg.1280x0_q85.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-IseiNdZqCg7dQRD0-ItWorksOnMyMachine.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-Jaupegd57IHxsSGE-57bad2c20c758f20b83b2344212a2a93.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/storage/app/file-manager/thumbnail-JVdvcCD7WcFNG6MF-ViewOfElephantinWater.jpg">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Sidebar.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="363">
<caret line="194" column="9" selection-start-line="194" selection-start-column="9" selection-end-line="194" selection-end-column="9" />
<folding>
<element signature="n#div#0;n#div#0;n#transition#0;n#template#0;n#!!top" />
<element signature="e#3246#3349#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/Alert.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="713">
<caret line="89" column="17" selection-start-line="89" selection-start-column="17" selection-end-line="89" selection-end-column="17" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app/Http/helpers.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="330">
<caret line="116" column="22" selection-start-line="116" selection-start-column="9" selection-end-line="116" selection-end-column="22" />
<folding>
<element signature="n#store_avatar#0;n#!!top" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/resources/js/helpers.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="320">
<caret line="148" column="38" selection-start-line="148" selection-start-column="22" selection-end-line="148" selection-end-column="38" />
<folding>
<element signature="e#0#33#0" expanded="true" />
<element signature="e#201#287#0" />
<element signature="e#730#1219#0" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/ToolbarButtonUpload.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="280">
<caret line="10" column="60" selection-start-line="10" selection-start-column="60" selection-end-line="10" selection-end-column="60" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/FileItemList.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="448">
<caret line="47" column="77" selection-start-line="47" selection-start-column="59" selection-end-line="47" selection-end-column="77" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Others/TextLabel.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="672">
<caret line="24" selection-start-line="21" selection-start-column="27" selection-end-line="24" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/.editorconfig">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/.env">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/resources/js/components/VueFileManager.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="560">
<caret line="20" column="26" selection-start-line="20" selection-start-column="17" selection-end-line="20" selection-end-column="26" />
<folding>
<element signature="e#618#695#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="187">
<caret line="57" column="40" selection-start-line="57" selection-start-column="40" selection-end-line="57" selection-end-column="40" />
<folding>
<element signature="e#314#409#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/public/mix-manifest.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="56">
<caret line="2" column="35" selection-start-line="2" selection-start-column="35" selection-end-line="2" selection-end-column="35" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/resources/js/components/DemoPageComponents/MobileMenu.vue">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/resources/js/main.js">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/resources/js/App.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="56">
<caret line="2" column="31" lean-forward="true" selection-start-line="2" selection-start-column="31" selection-end-line="2" selection-end-column="31" />
<folding>
<element signature="n#style#0;n#VueFileManager#0;n#div#0;n#template#0;n#!!top" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/webpack.mix.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="476">
<caret line="17" column="14" lean-forward="true" selection-start-line="17" selection-start-column="14" selection-end-line="17" selection-end-column="14" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/.styleci.yml">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/config/auth.php">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/resources/js/store/modules/filesView.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="594">
<caret line="185" column="48" selection-start-line="185" selection-start-column="12" selection-end-line="185" selection-end-column="48" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/resources/js/store/modules/userAuth.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2734">
<caret line="101" column="4" selection-start-line="101" selection-start-column="4" selection-end-line="101" selection-end-column="4" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/FilesView/ContextMenu.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="442">
<caret line="50" column="51" selection-start-line="50" selection-start-column="51" selection-end-line="50" selection-end-column="51" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app/Http/Controllers/AppFunctionsController.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-186">
<caret line="8" column="6" selection-start-line="8" selection-start-column="6" selection-end-line="8" selection-end-column="6" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app/FileManagerFolder.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="3342">
<caret line="120" column="5" selection-start-line="120" selection-start-column="5" selection-end-line="120" selection-end-column="5" />
<folding>
<element signature="e#23#41#0#PHP" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app/FileManagerFile.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-1682">
<caret line="13" column="6" selection-start-line="13" selection-start-column="6" selection-end-line="13" selection-end-column="6" />
<folding>
<element signature="e#23#44#0#PHP" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app/Http/Controllers/Auth/AuthController.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-2678">
<caret line="19" column="6" selection-start-line="19" selection-start-column="6" selection-end-line="19" selection-end-column="6" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app/Http/Controllers/UserAccountController.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-3070">
<caret line="14" column="6" selection-start-line="14" selection-start-column="6" selection-end-line="14" selection-end-column="6" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app/Http/Controllers/FileManagerController.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-11946">
<caret line="164" column="49" lean-forward="true" selection-start-line="164" selection-start-column="49" selection-end-line="164" selection-end-column="49" />
<folding>
<element signature="e#40#67#0#PHP" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/resources/views/index.blade.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="326">
<caret line="26" column="46" selection-start-line="26" selection-start-column="46" selection-end-line="26" selection-end-column="46" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/config/vuefilemanager.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="308">
<caret line="11" column="35" selection-start-line="11" selection-start-column="35" selection-end-line="11" selection-end-column="35" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/routes/web.php">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/routes/api.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-40">
<caret line="45" column="37" selection-start-line="45" selection-start-column="37" selection-end-line="45" selection-end-column="37" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/resources/js/components/VueFileManagerComponents/Auth.vue">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="201">
<caret line="516" column="13" selection-start-line="516" selection-start-column="13" selection-end-line="516" selection-end-column="13" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/resources/sass/vue-file-manager/_forms.scss">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="112">
<caret line="28" column="26" lean-forward="true" selection-start-line="28" selection-start-column="26" selection-end-line="28" selection-end-column="26" />
</state>
</provider>
</entry>
</component>
</project>

1317
.phpstorm.meta.php Normal file

File diff suppressed because it is too large Load Diff

BIN
.rnd Normal file

Binary file not shown.

112
README.md
View File

@@ -1,78 +1,52 @@
<p align="center"><img src="https://res.cloudinary.com/dtfbvvkyp/image/upload/v1566331377/laravel-logolockup-cmyk-red.svg" width="400"></p>
### Documentation
[Read online documentation](https://vuefilemanager.com/docs/)
<p align="center">
<a href="https://travis-ci.org/laravel/framework"><img src="https://travis-ci.org/laravel/framework.svg" alt="Build Status"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/d/total.svg" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/v/stable.svg" alt="Latest Stable Version"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/license.svg" alt="License"></a>
</p>
### Demo & dev preview links
* For visit demo version click here [demo.vuefilemanager.com](https://demo.vuefilemanager.com/)
* For visit dev version click here [dev.vuefilemanager.com](https://dev.vuefilemanager.com/) (It's auto deployed dev branch. Can be unstable and not ready for production)
## About Laravel
### Installation setup
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
Run these commands to install vendors:
```
composer install
```
```
npm install
```
- [Simple, fast routing engine](https://laravel.com/docs/routing).
- [Powerful dependency injection container](https://laravel.com/docs/container).
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
- [Robust background job processing](https://laravel.com/docs/queues).
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
Setup your database in .env and run this command:
```
php artisan setup:prod
```
Laravel is accessible, powerful, and provides tools required for large, robust applications.
It automatically:
* Migrate database
* Generate Application key
* Create Passport Encryption keys
* Create Password grant client
* Create Personal access client
## Learning Laravel
Then, copy generated password grant client `Client ID`, `Client secret` and paste it to .env files here:
```
PASSPORT_CLIENT_ID=<your_passport_client_id>
PASSPORT_CLIENT_SECRET=<your_passport_client_secret>
```
For sending forgoten password request via email, fill your mail driver in .env
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
### Run Application
To start server on your localhost, run this command
```
php artisan serve
```
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 1500 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
To compiles and hot-reloads for development, run this command
```
npm run hot
```
## Laravel Sponsors
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell).
- **[Vehikl](https://vehikl.com/)**
- **[Tighten Co.](https://tighten.co)**
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
- **[64 Robots](https://64robots.com)**
- **[Cubet Techno Labs](https://cubettech.com)**
- **[Cyber-Duck](https://cyber-duck.co.uk)**
- **[British Software Development](https://www.britishsoftware.co)**
- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
- **[DevSquad](https://devsquad.com)**
- [UserInsights](https://userinsights.com)
- [Fragrantica](https://www.fragrantica.com)
- [SOFTonSOFA](https://softonsofa.com/)
- [User10](https://user10.com)
- [Soumettre.fr](https://soumettre.fr/)
- [CodeBrisk](https://codebrisk.com)
- [1Forge](https://1forge.com)
- [TECPRESSO](https://tecpresso.co.jp/)
- [Runtime Converter](http://runtimeconverter.com/)
- [WebL'Agence](https://weblagence.com/)
- [Invoice Ninja](https://www.invoiceninja.com)
- [iMi digital](https://www.imi-digital.de/)
- [Earthlink](https://www.earthlink.ro/)
- [Steadfast Collective](https://steadfastcollective.com/)
- [We Are The Robots Inc.](https://watr.mx/)
- [Understand.io](https://www.understand.io/)
- [Abdel Elrafa](https://abdelelrafa.com)
- [Hyper Host](https://hyper.host)
- [Appoly](https://www.appoly.co.uk)
- [OP.GG](https://op.gg)
## Contributing
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
## Code of Conduct
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
## Security Vulnerabilities
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
## License
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
To compiles for production, run this command
```
npm run prod
```
That's all, happy coding! :tada: :tada: :tada:

18211
_ide_helper.php Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,66 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
class Deploy extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'deploy:production';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Automatic deployment for production';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
// Start deployment
$this->info('Running auto deployment');
$this->call('down');
// Exec commands
exec('git pull origin ' . config('app.deploy_branch'));
//exec('composer update --no-interaction --prefer-dist');
$this->migrateDatabase();
// Stop deployment
$this->call('up');
$this->info('Everything is done, congratulations! 🥳🥳🥳');
Log::info('Application was updated!');
}
/**
* Migrate database
*/
public function migrateDatabase()
{
$this->call('migrate', [
'--force' => true,
]);
}
}

View File

@@ -0,0 +1,124 @@
<?php
namespace App\Console\Commands;
use App\User;
use App\UserSettings;
use Illuminate\Console\Command;
class SetupDevEnvironment extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'setup:dev';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Setting production environment';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->info('Setting up production environment');
$this->migrateDatabase();
$this->generateKey();
$this->createPassportKeys();
$this->createPassportClientPassword();
$this->createPassportClientPersonal();
$this->createDefaultUser();
$this->info('Everything is done, congratulations! 🥳🥳🥳');
}
/**
* Migrate database
*/
public function generateKey()
{
$this->call('key:generate');
}
/**
* Migrate database
*/
public function migrateDatabase()
{
$this->call('migrate:fresh');
}
/**
* Create Passport Encryption keys
*/
public function createPassportKeys()
{
$this->call('passport:keys', [
'--force' => true
]);
}
/**
* Create Password grant client
*/
public function createPassportClientPassword()
{
$this->call('passport:client', [
'--password' => true,
'--name' => 'vuefilemanager',
]);
$this->alert('Please copy these first password grant Client ID & Client secret above to your /.env file.');
}
/**
* Create Personal access client
*/
public function createPassportClientPersonal()
{
$this->call('passport:client', [
'--personal' => true,
'--name' => 'shared',
]);
}
/**
* Create Default User
*/
public function createDefaultUser()
{
$user = User::create([
'name' => 'Jane Doe',
'email' => 'howdy@hi5ve.digital',
'role' => 'admin',
'password' => \Hash::make('vuefilemanager'),
]);
// Create settings
$settings = UserSettings::create([
'user_id' => $user->id
]);
$this->info('Test user created. Email: ' . $user->email . ' Password: vuefilemanager');
}
}

View File

@@ -0,0 +1,101 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class SetupProductionEnvironment extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'setup:prod';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Setting production environment';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->info('Setting up production environment');
$this->migrateDatabase();
$this->generateKey();
$this->createPassportKeys();
$this->createPassportClientPassword();
$this->createPassportClientPersonal();
$this->info('Everything is done, congratulations! 🥳🥳🥳');
}
/**
* Migrate database
*/
public function generateKey()
{
$this->call('key:generate');
}
/**
* Migrate database
*/
public function migrateDatabase()
{
$this->call('migrate:fresh');
}
/**
* Create Passport Encryption keys
*/
public function createPassportKeys()
{
$this->call('passport:keys', [
'--force' => true
]);
}
/**
* Create Password grant client
*/
public function createPassportClientPassword()
{
$this->call('passport:client', [
'--password' => true,
'--name' => 'vuefilemanager',
]);
$this->alert('Please copy these first password grant Client ID & Client secret above to your /.env file.');
}
/**
* Create Personal access client
*/
public function createPassportClientPersonal()
{
$this->call('passport:client', [
'--personal' => true,
'--name' => 'shared',
]);
}
}

View File

@@ -0,0 +1,88 @@
<?php
namespace App\Console\Commands;
use App\User;
use App\UserSettings;
use Illuminate\Console\Command;
class UpgradeApp extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'upgrade:app {version}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Upgrade application to new version';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->info('Upgrading your application to version ' . $this->argument('version'));
$this->call('down');
// Version 1.6
if ($this->argument('version') === 'v1.6') {
$this->version_1_6();
}
$this->call('up');
$this->info('Your application was upgraded! 🥳🥳🥳');
}
/**
* Upgrade script to version 1.6
*/
public function version_1_6() {
// Migrate new tables and changes
$this->call('migrate');
// Create user settings records
$this->info('Updating users options...');
User::all()->each(function ($user) {
$this->info('Update user with id: ' . $user->id);
UserSettings::create(['user_id' => $user->id]);
});
$this->info('Updating user options is done!');
// Set up admin
$email = $this->ask('Which user would you like set up as admin? Please type user email');
$admin = User::where('email', $email)->first();
if (! $admin) {
$email = $this->ask('We can\'t find user with this email, please try it again');
$admin = User::where('email', $email)->first();
}
// Save new role for selected user
$admin->role = 'admin';
$admin->save();
$this->info('Admin was set up successfully');
}
}

View File

@@ -2,6 +2,10 @@
namespace App\Console;
use App\Console\Commands\Deploy;
use App\Console\Commands\SetupDevEnvironment;
use App\Console\Commands\SetupProductionEnvironment;
use App\Console\Commands\UpgradeApp;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
@@ -13,7 +17,10 @@ class Kernel extends ConsoleKernel
* @var array
*/
protected $commands = [
//
SetupProductionEnvironment::class,
SetupDevEnvironment::class,
UpgradeApp::class,
Deploy::class,
];
/**

View File

@@ -3,18 +3,61 @@
namespace App;
use ByteUnits\Metric;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Laravel\Scout\Searchable;
use TeamTNT\TNTSearch\Indexer\TNTIndexer;
use \Illuminate\Database\Eloquent\SoftDeletes;
use \Askedio\SoftCascade\Traits\SoftCascadeTrait;
/**
* App\FileManagerFile
*
* @property int $id
* @property int|null $user_id
* @property int $unique_id
* @property int $folder_id
* @property string $thumbnail
* @property string|null $name
* @property string|null $basename
* @property string|null $mimetype
* @property string $filesize
* @property string|null $type
* @property string $user_scope
* @property string $deleted_at
* @property string $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \App\FileManagerFolder|null $folder
* @property-read string $file_url
* @property-read \App\FileManagerFolder $parent
* @property-read \App\Share|null $shared
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile newQuery()
* @method static \Illuminate\Database\Query\Builder|\App\FileManagerFile onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile query()
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile whereBasename($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile whereDeletedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile whereFilesize($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile whereFolderId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile whereMimetype($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile whereThumbnail($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile whereType($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile whereUniqueId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile whereUserId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFile whereUserScope($value)
* @method static \Illuminate\Database\Query\Builder|\App\FileManagerFile withTrashed()
* @method static \Illuminate\Database\Query\Builder|\App\FileManagerFile withoutTrashed()
* @mixin \Eloquent
*/
class FileManagerFile extends Model
{
use Searchable, SoftDeletes, SoftCascadeTrait;
use Searchable, SoftDeletes;
public $public_access = null;
protected $guarded = [
'id'
@@ -24,6 +67,16 @@ class FileManagerFile extends Model
'file_url'
];
/**
* Set routes with public access
*
* @param $token
*/
public function setPublicUrl($token)
{
$this->public_access = $token;
}
/**
* Format created at date
*
@@ -31,7 +84,7 @@ class FileManagerFile extends Model
*/
public function getCreatedAtAttribute()
{
return Carbon::create($this->attributes['created_at'])->format('j M Y \a\t H:i');;
return format_date($this->attributes['created_at'], __('vuefilemanager.time'));
}
/**
@@ -41,15 +94,14 @@ class FileManagerFile extends Model
*/
public function getDeletedAtAttribute()
{
if (! $this->attributes['deleted_at']) return null;
if (!$this->attributes['deleted_at']) return null;
return Carbon::create($this->attributes['deleted_at'])->format('j M Y at H:i');
return format_date($this->attributes['deleted_at'], __('vuefilemanager.time'));
}
/**
* Format filesize
* Format fileSize
*
* @param $value
* @return string
*/
public function getFilesizeAttribute()
@@ -60,23 +112,64 @@ class FileManagerFile extends Model
/**
* Format thumbnail url
*
* @param $value
* @return string
*/
public function getThumbnailAttribute()
{
return $this->attributes['thumbnail'] ? route('thumbnail', ['name' => $this->attributes['thumbnail']]) : null;
// Get thumbnail from s3
if ($this->attributes['thumbnail'] && is_storage_driver(['s3', 'spaces'])) {
return Storage::temporaryUrl('file-manager/' . $this->attributes['thumbnail'], now()->addDay());
}
// Get thumbnail from local storage
if ($this->attributes['thumbnail'] && is_storage_driver('local')) {
// Thumbnail route
$route = route('thumbnail', ['name' => $this->attributes['thumbnail']]);
if ($this->public_access) {
return $route . '/public/' . $this->public_access;
}
return $route;
}
return null;
}
/**
* Format file url
*
* @param $value
* @return string
*/
public function getFileUrlAttribute()
{
return route('file', ['name' => $this->attributes['basename']]);
// Get file from s3
if (is_storage_driver(['s3', 'spaces'])) {
$header = [
"ResponseAcceptRanges" => "bytes",
"ResponseContentType" => $this->attributes['mimetype'],
"ResponseContentLength" => $this->attributes['filesize'],
"ResponseContentRange" => "bytes 0-600/" . $this->attributes['filesize'],
'ResponseContentDisposition' => 'attachment; filename=' . $this->attributes['name'] . '.' . $this->attributes['mimetype'],
];
return Storage::temporaryUrl('file-manager/' . $this->attributes['basename'], now()->addDay(), $header);
}
// Get thumbnail from local storage
if (is_storage_driver('local')) {
$route = route('file', ['name' => $this->attributes['basename']]);
if ($this->public_access) {
return $route . '/public/' . $this->public_access;
}
return $route;
}
}
/**
@@ -115,4 +208,14 @@ class FileManagerFile extends Model
{
return $this->hasOne('App\FileManagerFolder', 'unique_id', 'folder_id');
}
/**
* Get sharing attributes
*
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function shared()
{
return $this->hasOne('App\Share', 'item_id', 'unique_id');
}
}

View File

@@ -11,20 +11,62 @@ use RecursiveArrayIterator;
use RecursiveIteratorIterator;
use TeamTNT\TNTSearch\Indexer\TNTIndexer;
use \Illuminate\Database\Eloquent\SoftDeletes;
use \Askedio\SoftCascade\Traits\SoftCascadeTrait;
/**
* App\FileManagerFolder
*
* @property int $id
* @property int|null $user_id
* @property int $unique_id
* @property int $parent_id
* @property string|null $name
* @property string|null $type
* @property string $user_scope
* @property string $deleted_at
* @property string $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Illuminate\Database\Eloquent\Collection|\App\FileManagerFolder[] $children
* @property-read int|null $children_count
* @property-read \Illuminate\Database\Eloquent\Collection|\App\FileManagerFile[] $files
* @property-read int|null $files_count
* @property-read \Illuminate\Database\Eloquent\Collection|\App\FileManagerFolder[] $folders
* @property-read int|null $folders_count
* @property-read int $items
* @property-read int $trashed_items
* @property-read \App\FileManagerFolder $parent
* @property-read \App\Share|null $shared
* @property-read \Illuminate\Database\Eloquent\Collection|\App\FileManagerFolder[] $trashed_children
* @property-read int|null $trashed_children_count
* @property-read \Illuminate\Database\Eloquent\Collection|\App\FileManagerFile[] $trashed_files
* @property-read int|null $trashed_files_count
* @property-read \Illuminate\Database\Eloquent\Collection|\App\FileManagerFolder[] $trashed_folders
* @property-read int|null $trashed_folders_count
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFolder newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFolder newQuery()
* @method static \Illuminate\Database\Query\Builder|\App\FileManagerFolder onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFolder query()
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFolder whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFolder whereDeletedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFolder whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFolder whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFolder whereParentId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFolder whereType($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFolder whereUniqueId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFolder whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFolder whereUserId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\FileManagerFolder whereUserScope($value)
* @method static \Illuminate\Database\Query\Builder|\App\FileManagerFolder withTrashed()
* @method static \Illuminate\Database\Query\Builder|\App\FileManagerFolder withoutTrashed()
* @mixin \Eloquent
*/
class FileManagerFolder extends Model
{
use Searchable, SoftDeletes, SoftCascadeTrait;
use Searchable, SoftDeletes;
protected $guarded = [
'id'
];
protected $softCascade = [
'children', 'files'
];
protected $appends = [
'items', 'trashed_items'
];
@@ -79,7 +121,7 @@ class FileManagerFolder extends Model
*/
public function getCreatedAtAttribute()
{
return Carbon::create($this->attributes['created_at'])->format('j M Y \a\t H:i');
return format_date($this->attributes['created_at'], __('vuefilemanager.time'));
}
/**
@@ -91,7 +133,7 @@ class FileManagerFolder extends Model
{
if (! $this->attributes['deleted_at']) return null;
return Carbon::create($this->attributes['deleted_at'])->format('j M Y \a\t H:i');
return format_date($this->attributes['deleted_at'], __('vuefilemanager.time'));
}
/**
@@ -116,7 +158,6 @@ class FileManagerFolder extends Model
*/
public function files()
{
return $this->hasMany('App\FileManagerFile', 'folder_id', 'unique_id');
}
@@ -171,6 +212,16 @@ class FileManagerFolder extends Model
return $this->hasMany('App\FileManagerFolder', 'parent_id', 'unique_id')->withTrashed();
}
/**
* Get sharing attributes
*
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function shared()
{
return $this->hasOne('App\Share', 'item_id', 'unique_id');
}
// Delete all folder childrens
public static function boot()
{
@@ -178,9 +229,22 @@ class FileManagerFolder extends Model
static::deleting(function ($item) {
$item->children()->each(function($folder) {
$folder->delete();
});
if ( $item->isForceDeleting() ) {
$item->trashed_children()->each(function($folder) {
$folder->forceDelete();
});
} else {
$item->children()->each(function($folder) {
$folder->delete();
});
$item->files()->each(function($file) {
$file->delete();
});
}
});
static::restoring(function ($item) {
@@ -196,4 +260,4 @@ class FileManagerFolder extends Model
});
});
}
}
}

View File

@@ -0,0 +1,222 @@
<?php
namespace App\Http\Controllers\Admin;
use App\FileManagerFile;
use App\FileManagerFolder;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\ChangeRoleRequest;
use App\Http\Requests\Admin\ChangeStorageCapacityRequest;
use App\Http\Requests\Admin\CreateUserByAdmin;
use App\Http\Requests\Admin\DeleteUserRequest;
use App\Http\Resources\UsersCollection;
use App\Http\Resources\UserResource;
use App\Http\Resources\UserStorageResource;
use App\Http\Tools\Demo;
use App\Share;
use App\User;
use App\UserSettings;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;
use Storage;
class UserController extends Controller
{
/**
* Get user details
*
* @param $id
* @return UserResource
*/
public function details($id)
{
return new UserResource(User::findOrFail($id));
}
/**
* Get user storage details
*
* @param $id
* @return UserStorageResource
*/
public function storage($id)
{
return new UserStorageResource(User::findOrFail($id));
}
/**
* Get all users
*
* @return UsersCollection
*/
public function users()
{
return new UsersCollection(User::all());
}
/**
* Change user role
*
* @param ChangeRoleRequest $request
* @param $id
* @return UserResource
*/
public function change_role(ChangeRoleRequest $request, $id)
{
$user = User::findOrFail($id);
// Demo preview
if (env('APP_DEMO') && $id == 1) {
return new UserResource($user);
}
$user->update($request->input('attributes'));
return new UserResource($user);
}
/**
* Change user storage capacity
*
* @param ChangeStorageCapacityRequest $request
* @param $id
* @return UserStorageResource
*/
public function change_storage_capacity(ChangeStorageCapacityRequest $request, $id)
{
$user = User::findOrFail($id);
$user->settings()->update($request->input('attributes'));
return new UserStorageResource($user);
}
/**
* Send user password reset link
*
* @param $id
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function send_password_reset_email($id)
{
$user = User::findOrFail($id);
// Demo preview
if (env('APP_DEMO')) {
return response('Done!', 204);
}
// Get password token
$token = Password::getRepository()->create($user);
// Send user email
$user->sendPasswordResetNotification($token);
return response('Done!', 204);
}
/**
* Create new user by admin
*
* @param CreateUserByAdmin $request
* @return UserResource
*/
public function create_user(CreateUserByAdmin $request)
{
// Store avatar
if ($request->hasFile('avatar')) {
// Update avatar
$avatar = store_avatar($request->file('avatar'), 'avatars');
}
// Create user
$user = User::create([
'avatar' => $request->hasFile('avatar') ? $avatar : null,
'name' => $request->name,
'role' => $request->role,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
// Create settings
$settings = UserSettings::create([
'user_id' => $user->id,
'storage_capacity' => $request->storage_capacity,
]);
return new UserResource($user);
}
/**
* Delete user with all user data
*
* @param DeleteUserRequest $request
* @param $id
* @return ResponseFactory|\Illuminate\Http\Response
* @throws \Exception
*/
public function delete_user(DeleteUserRequest $request, $id)
{
$user = User::findOrFail($id);
// Demo preview
if (env('APP_DEMO')) {
return response('Done!', 204);
}
// Check for self deleted account
if ($user->id === Auth::id()) {
abort(406, 'You can\'t delete your account');
}
// Validate user name
if ($user->name !== $request->name) abort(403);
$shares = Share::where('user_id', $user->id)->get();
$files = FileManagerFile::withTrashed()
->where('user_id', $user->id)
->get();
$folders = FileManagerFolder::withTrashed()
->where('user_id', $user->id)
->get();
// Remove all files and thumbnails
$files->each(function ($file) {
// Delete file
Storage::delete('/file-manager/' . $file->basename);
// Delete thumbnail if exist
if (!is_null($file->thumbnail)) {
Storage::delete('/file-manager/' . $file->getOriginal('thumbnail'));
}
// Delete file permanently
$file->forceDelete();
});
// Remove avatar
if ($user->avatar) {
Storage::delete('/avatars/' . $user->avatar);
}
// Remove folders & shares
$folders->each->forceDelete();
$shares->each->forceDelete();
// Remove favourites
$user->settings->delete();
$user->favourites()->sync([]);
// Delete user
$user->delete();
return response('Done!', 204);
}
}

View File

@@ -2,8 +2,9 @@
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Response;
class AppFunctionsController extends Controller
@@ -17,28 +18,4 @@ class AppFunctionsController extends Controller
{
return view("index");
}
/**
* Get file
*
* @param $filename
* @return mixed
*/
public function get_avatar($basename)
{
// Get file path
$path = storage_path() . '/app/avatars/' . $basename;
// Check if file exist
if (!File::exists($path)) abort(404);
$file = File::get($path);
$type = File::mimeType($path);
// Create response
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
return $response;
}
}

View File

@@ -2,20 +2,14 @@
namespace App\Http\Controllers\Auth;
use App\ClientProfile;
use App\Models\User\UserAttribute;
use App\Models\User\UserNotificationSetting;
use App\ProviderProfile;
use App\Http\Requests\Auth\CheckAccountRequest;
use App\User;
use GuzzleHttp\Client;
use App\UserSettings;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Validator;
class AuthController extends Controller
{
@@ -26,12 +20,7 @@ class AuthController extends Controller
* @param Request $request
* @return mixed
*/
public function check_account(Request $request) {
// Validate request
$request->validate([
'email' => ['required', 'string', 'email'],
]);
public function check_account(CheckAccountRequest $request) {
// Get User
$user = User::where('email', $request->input('email'))->select(['name', 'avatar'])->first();
@@ -43,7 +32,7 @@ class AuthController extends Controller
];
// Abort with 404, user not found
return abort('404', 'We can\'t find a user with that e-mail address.');
return abort('404', __('vuefilemanager.user_not_fount'));
}
/**
* Login user
@@ -59,7 +48,7 @@ class AuthController extends Controller
$data = json_decode($response->content(), true);
return response('Login Successfull!', 200)->cookie('token', $data['access_token'], 43200);
return response('Login Successfull!', 200)->cookie('access_token', $data['access_token'], 43200);
} else {
return $response;
@@ -85,19 +74,24 @@ class AuthController extends Controller
]);
// Create user
User::create([
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
// Create settings
$settings = UserSettings::create([
'user_id' => $user->id
]);
$response = Route::dispatch(self::make_request($request));
if ($response->isSuccessful()) {
$data = json_decode($response->content(), true);
return response('Register Successfull!', 200)->cookie('token', $data['access_token'], 43200);
return response('Register Successfull!', 200)->cookie('access_token', $data['access_token'], 43200);
} else {
return $response;
@@ -111,6 +105,12 @@ class AuthController extends Controller
*/
public function logout()
{
// Demo preview
if (is_demo( Auth::id())) {
return response('Logout successfull', 204)
->cookie('access_token', '', -1);
}
// Get user tokens and remove it
auth()->user()->tokens()->each(function ($token) {
@@ -118,7 +118,8 @@ class AuthController extends Controller
$token->delete();
});
return response('Logout successfull', 200)->cookie('token', '', -1);
return response('Logout successfull', 204)
->cookie('access_token', '', -1);
}
/**
@@ -128,7 +129,7 @@ class AuthController extends Controller
* @param string $provider
* @return Request
*/
private static function make_request(Request $request)
private static function make_request($request)
{
$request->request->add([
'grant_type' => 'password',
@@ -136,7 +137,7 @@ class AuthController extends Controller
'client_secret' => config('services.passport.client_secret'),
'username' => $request->email,
'password' => $request->password,
'scope' => '',
'scope' => 'master',
]);
return Request::create(url('/oauth/token'), 'POST', $request->all());

View File

@@ -0,0 +1,44 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Artisan;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\UnauthorizedException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class DeployController extends Controller
{
/**
* Get web hook payload and verify request
*
* @param Request $request
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function github(Request $request) {
if (($signature = $request->headers->get('X-Hub-Signature')) == null) {
throw new BadRequestHttpException('Header not set');
}
$signature_parts = explode('=', $signature);
if (count($signature_parts) != 2) {
throw new BadRequestHttpException('signature has invalid format');
}
$known_signature = hash_hmac('sha1', $request->getContent(), config('app.deploy_secret'));
if (! hash_equals($known_signature, $signature_parts[1])) {
throw new UnauthorizedException('Could not verify request signature ' . $signature_parts[1]);
}
// Run deploying
Artisan::call('deploy:production');
Log::info('The GitHub webhook was accepted');
return response('The GitHub webhook was accepted', 202);
}
}

View File

@@ -0,0 +1,217 @@
<?php
namespace App\Http\Controllers;
use App\FileManagerFolder;
use App\Http\Tools\Guardian;
use App\Share;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Http\Request;
use App\FileManagerFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Response;
class FileAccessController extends Controller
{
/**
* Get avatar
*
* @param $basename
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function get_avatar($basename)
{
// Get file path
$path = '/avatars/' . $basename;
// Check if file exist
if (!Storage::exists($path)) abort(404);
// Return avatar
return Storage::download($path, $basename);
}
/**
* Get file
*
* @param Request $request
* @param $filename
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function get_file(Request $request, $filename)
{
// Get user id
$user_id = Auth::id();
// Get file record
$file = FileManagerFile::withTrashed()
->where('user_id', $user_id)
->where('basename', $filename)
->firstOrFail();
// Check user permission
if (!$request->user()->tokenCan('master')) {
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// Check access to file
$this->check_file_access($shared, $file);
}
return $this->download_file($file);
}
/**
* Get file public
*
* @param $filename
* @param $token
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function get_file_public($filename, $token)
{
// Get sharing record
$shared = get_shared($token);
// Abort if shared is protected
if ($shared->protected) {
abort(403, "Sorry, you don't have permission");
}
// Get file record
$file = FileManagerFile::where('user_id', $shared->user_id)
->where('basename', $filename)
->firstOrFail();
// Check file access
$this->check_file_access($shared, $file);
return $this->download_file($file);
}
/**
* Get image thumbnail
*
* @param Request $request
* @param $filename
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function get_thumbnail(Request $request, $filename)
{
// Get file record
$file = FileManagerFile::withTrashed()
->where('user_id', $request->user()->id)
->where('thumbnail', $filename)
->firstOrFail();
// Check user permission
if (!$request->user()->tokenCan('master')) {
$this->check_file_access($request, $file);
}
return $this->thumbnail_file($file);
}
/**
* Get public image thumbnail
*
* @param $filename
* @param $token
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function get_thumbnail_public($filename, $token)
{
// Get sharing record
$shared = get_shared($token);
// Abort if thumbnail is protected
if ($shared->protected) {
abort(403, "Sorry, you don't have permission");
}
// Get file record
$file = FileManagerFile::where('user_id', $shared->user_id)
->where('thumbnail', $filename)
->firstOrFail();
// Check file access
$this->check_file_access($shared, $file);
return $this->thumbnail_file($file);
}
/**
* Check user file access
*
* @param $shared
* @param $file
*/
protected function check_file_access($shared, $file): void
{
// Check by parent folder permission
if ($shared->type === 'folder') {
Guardian::check_item_access($file->folder_id, $shared);
}
// Check by single file permission
if ($shared->type === 'file') {
if ($shared->item_id !== $file->unique_id) abort(403);
}
}
/**
* Call and download file
*
* @param $file
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
private function download_file($file)
{
// Format pretty filename
$file_pretty_name = $file->name . '.' . $file->mimetype;
// Get file path
$path = '/file-manager/' . $file->basename;
// Check if file exist
if (!Storage::exists($path)) abort(404);
$header = [
"Content-Type" => Storage::mimeType($path),
"Content-Length" => Storage::size($path),
"Accept-Ranges" => "bytes",
"Content-Range" => "bytes 0-600/" . Storage::size($path),
];
// Get file
return Storage::download($path, $file_pretty_name, $header);
}
/**
* @param $file
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
private function thumbnail_file($file)
{
// Get file path
$path = '/file-manager/' . $file->getOriginal('thumbnail');
// Check if file exist
if (!Storage::exists($path)) abort(404);
// Return image thumbnail
return Storage::download($path, $file->getOriginal('thumbnail'));
}
}

View File

@@ -0,0 +1,224 @@
<?php
namespace App\Http\Controllers\FileBrowser;
use App\Http\Requests\FileBrowser\SearchRequest;
use App\User;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Support\Collection;
use Illuminate\Http\Request;
use App\FileManagerFolder;
use App\FileManagerFile;
use App\Share;
class BrowseController extends Controller
{
/**
* Get trashed files
*
* @return Collection
*/
public function trash()
{
// Get user id
$user_id = Auth::id();
// Get folders and files
$folders_trashed = FileManagerFolder::onlyTrashed()
->with(['trashed_folders', 'parent'])
->where('user_id', $user_id)
->get(['parent_id', 'unique_id', 'name']);
$folders = FileManagerFolder::onlyTrashed()
->with(['parent'])
->where('user_id', $user_id)
->whereIn('unique_id', filter_folders_ids($folders_trashed))
->get();
// Get files trashed
$files_trashed = FileManagerFile::onlyTrashed()
->with(['parent'])
->where('user_id', $user_id)
->whereNotIn('folder_id', array_values(array_unique(recursiveFind($folders_trashed->toArray(), 'unique_id'))))
->get();
// Collect folders and files to single array
return collect([$folders, $files_trashed])->collapse();
}
/**
* Get user shared items
*
* @return Collection
*/
public function shared()
{
// Get user
$user_id = Auth::id();
// Get shared folders and files
$folder_ids = Share::where('user_id', $user_id)
->where('type', 'folder')
->pluck('item_id');
$file_ids = Share::where('user_id', $user_id)
->where('type', '!=', 'folder')
->pluck('item_id');
// Get folders and files
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected'])
->where('user_id', $user_id)
->whereIn('unique_id', $folder_ids)
->get();
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected'])
->where('user_id', $user_id)
->whereIn('unique_id', $file_ids)
->get();
// Collect folders and files to single array
return collect([$folders, $files])->collapse();
}
/**
* Get latest user uploads
*
* @return mixed
*/
public function latest() {
// Get User
$user = User::with(['latest_uploads'])
->where('id', Auth::id())
->first();
return $user->latest_uploads->makeHidden(['user_id', 'basename']);
}
/**
* Get participant uploads
*
* @return mixed
*/
public function participant_uploads() {
// Get User
$uploads = FileManagerFile::with(['parent'])->where('user_id', Auth::id())
->whereUserScope('editor')->orderBy('created_at', 'DESC')->get();
return $uploads;
}
/**
* Get directory with files
*
* @param Request $request
* @param $unique_id
* @return Collection
*/
public function folder(Request $request, $unique_id)
{
// Get user
$user_id = Auth::id();
// Get folder trash items
if ($request->query('trash')) {
// Get folders and files
$folders = FileManagerFolder::onlyTrashed()
->with('parent')
->where('user_id', $user_id)
->where('parent_id', $unique_id)
->get();
$files = FileManagerFile::onlyTrashed()
->with('parent')
->where('user_id', $user_id)
->where('folder_id', $unique_id)
->get();
// Collect folders and files to single array
return collect([$folders, $files])->collapse();
}
// Get folders and files
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected'])
->where('user_id', $user_id)
->where('parent_id', $unique_id)
->get();
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected'])
->where('user_id', $user_id)
->where('folder_id', $unique_id)
->orderBy('created_at', 'DESC')
->get();
// Collect folders and files to single array
return collect([$folders, $files])->collapse();
}
/**
* Get user folder tree
*
* @return array
*/
public function navigation_tree() {
$folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('parent_id', 0)
->where('user_id', Auth::id())
->get(['id', 'parent_id', 'unique_id', 'name']);
return [
[
'unique_id' => 0,
'name' => __('vuefilemanager.home'),
'location' => 'base',
'folders' => $folders,
]
];
}
/**
* Search files
*
* @param Request $request
* @return \Illuminate\Database\Eloquent\Collection
*/
public function search(SearchRequest $request)
{
// Get user
$user_id = Auth::id();
// Search files id db
$searched_files = FileManagerFile::search($request->input('query'))
->where('user_id', $user_id)
->get();
$searched_folders = FileManagerFolder::search($request->input('query'))
->where('user_id', $user_id)
->get();
// Collect folders and files to single array
return collect([$searched_folders, $searched_files])->collapse();
}
/**
* Get file record
*
* @param $unique_id
* @return mixed
*/
public function file_detail($unique_id)
{
// Get user id
$user_id = Auth::id();
return FileManagerFile::with(['shared:token,id,item_id,permission,protected'])
->where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
}
}

View File

@@ -0,0 +1,390 @@
<?php
namespace App\Http\Controllers\FileFunctions;
use App\Http\Requests\FileFunctions\CreateFolderRequest;
use App\Http\Requests\FileFunctions\DeleteItemRequest;
use App\Http\Requests\FileFunctions\RenameItemRequest;
use App\Http\Requests\FileFunctions\MoveItemRequest;
use App\Http\Requests\FileFunctions\UploadRequest;
use App\Http\Tools\Demo;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use App\Http\Tools\Guardian;
use App\Http\Tools\Editor;
use App\FileManagerFile;
use Exception;
class EditItemsController extends Controller
{
/**
* Create new folder for authenticated master|editor user
*
* @param CreateFolderRequest $request
* @return array
* @throws Exception
*/
public function user_create_folder(CreateFolderRequest $request)
{
// Demo preview
if (is_demo(Auth::id())) {
return Demo::create_folder($request);
}
// Check permission to create folder for authenticated editor
if ($request->user()->tokenCan('editor')) {
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// Check access to requested directory
Guardian::check_item_access($request->parent_id, $shared);
}
// Create new folder
return Editor::create_folder($request);
}
/**
* Create new folder for guest user with edit permission
*
* @param CreateFolderRequest $request
* @param $token
* @return array
* @throws Exception
*/
public function guest_create_folder(CreateFolderRequest $request, $token)
{
// Get shared record
$shared = get_shared($token);
if (is_demo($shared->user_id)) {
return Demo::create_folder($request);
}
// Check shared permission
if (!is_editor($shared)) abort(403);
// Check access to requested directory
Guardian::check_item_access($request->parent_id, $shared);
// Create folder
return Editor::create_folder($request, $shared);
}
/**
* Rename item for authenticated master|editor user
*
* @param RenameItemRequest $request
* @param $unique_id
* @return mixed
* @throws Exception
*/
public function user_rename_item(RenameItemRequest $request, $unique_id)
{
// Demo preview
if (is_demo(Auth::id())) {
return Demo::rename_item($request, $unique_id);
}
// Check permission to rename item for authenticated editor
if ($request->user()->tokenCan('editor')) {
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// Get file|folder item
$item = get_item($request->type, $unique_id, Auth::id());
// Check access to requested directory
if ($request->type === 'folder') {
Guardian::check_item_access($item->unique_id, $shared);
} else {
Guardian::check_item_access($item->folder_id, $shared);
}
}
// Rename Item
return Editor::rename_item($request, $unique_id);
}
/**
* Rename item for guest user with edit permission
*
* @param RenameItemRequest $request
* @param $unique_id
* @param $token
* @return mixed
* @throws Exception
*/
public function guest_rename_item(RenameItemRequest $request, $unique_id, $token)
{
// Get shared record
$shared = get_shared($token);
// Demo preview
if (is_demo($shared->user_id)) {
return Demo::rename_item($request, $unique_id);
}
// Check shared permission
if (!is_editor($shared)) abort(403);
// Get file|folder item
$item = get_item($request->type, $unique_id, $shared->user_id);
// Check access to requested item
if ($request->type === 'folder') {
Guardian::check_item_access($item->unique_id, $shared);
} else {
Guardian::check_item_access($item->folder_id, $shared);
}
// Rename item
$item = Editor::rename_item($request, $unique_id, $shared);
// Set public url
if ($item->type !== 'folder') {
$item->setPublicUrl($token);
}
return $item;
}
/**
* Delete item for authenticated master|editor user
*
* @param DeleteItemRequest $request
* @param $unique_id
* @return ResponseFactory|\Illuminate\Http\Response
* @throws Exception
*/
public function user_delete_item(DeleteItemRequest $request, $unique_id)
{
// Demo preview
if (is_demo(Auth::id())) {
return Demo::response_204();
}
// Check permission to delete item for authenticated editor
if ($request->user()->tokenCan('editor')) {
// Prevent force delete for non-master users
if ($request->force_delete) abort('401');
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// Get file|folder item
$item = get_item($request->type, $unique_id, Auth::id());
// Check access to requested directory
if ($request->type === 'folder') {
Guardian::check_item_access($item->unique_id, $shared);
} else {
Guardian::check_item_access($item->folder_id, $shared);
}
}
// Delete item
Editor::delete_item($request, $unique_id);
// Return response
return response(null, 204);
}
/**
* Delete item for guest user with edit permission
*
* @param DeleteItemRequest $request
* @param $unique_id
* @param $token
* @return ResponseFactory|\Illuminate\Http\Response
* @throws Exception
*/
public function guest_delete_item(DeleteItemRequest $request, $unique_id, $token)
{
// Get shared record
$shared = get_shared($token);
// Demo preview
if (is_demo($shared->user_id)) {
return Demo::response_204();
}
// Check shared permission
if (!is_editor($shared)) abort(403);
// Get file|folder item
$item = get_item($request->type, $unique_id, $shared->user_id);
// Check access to requested item
if ($request->type === 'folder') {
Guardian::check_item_access($item->unique_id, $shared);
} else {
Guardian::check_item_access($item->folder_id, $shared);
}
// Delete item
Editor::delete_item($request, $unique_id, $shared);
// Return response
return response(null, 204);
}
/**
* Delete file for authenticated master|editor user
*
* @param UploadRequest $request
* @return FileManagerFile|Model
* @throws Exception
*/
public function user_upload(UploadRequest $request)
{
// Demo preview
if (is_demo(Auth::id())) {
return Demo::upload($request);
}
// Check if user can upload
if (config('vuefilemanager.limit_storage_by_capacity') && user_storage_percentage() >= 100) {
abort(423, 'You exceed your storage limit!');
}
// Check permission to upload for authenticated editor
if ($request->user()->tokenCan('editor')) {
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// Check access to requested directory
Guardian::check_item_access($request->parent_id, $shared);
}
// Return new uploaded file
return Editor::upload($request);
}
/**
* Delete file for guest user with edit permission
*
* @param UploadRequest $request
* @param $token
* @return FileManagerFile|Model
* @throws Exception
*/
public function guest_upload(UploadRequest $request, $token)
{
// Get shared record
$shared = get_shared($token);
// Demo preview
if (is_demo($shared->user_id)) {
return Demo::upload($request);
}
// Check shared permission
if (!is_editor($shared)) abort(403);
// Check access to requested directory
Guardian::check_item_access($request->parent_id, $shared);
// Return new uploaded file
$new_file = Editor::upload($request, $shared);
// Set public access url
$new_file->setPublicUrl($token);
return $new_file;
}
/**
* Move item for authenticated master|editor user
*
* @param MoveItemRequest $request
* @param $unique_id
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function user_move(MoveItemRequest $request, $unique_id)
{
// Demo preview
if (is_demo(Auth::id())) {
return Demo::response_204();
}
// Check permission to upload for authenticated editor
if ($request->user()->tokenCan('editor')) {
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// Check access to requested directory
Guardian::check_item_access($request->to_unique_id, $shared);
}
// Move item
Editor::move($request, $unique_id);
return response('Done!', 204);
}
/**
* Move item for guest user with edit permission
*
* @param MoveItemRequest $request
* @param $unique_id
* @param $token
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function guest_move(MoveItemRequest $request, $unique_id, $token)
{
// Get shared record
$shared = get_shared($token);
// Demo preview
if (is_demo(Auth::id())) {
return Demo::response_204();
}
// Check shared permission
if (!is_editor($shared)) abort(403);
$moving_unique_id = $unique_id;
if ($request->from_type !== 'folder') {
$file = FileManagerFile::where('unique_id', $unique_id)
->where('user_id', $shared->user_id)
->firstOrFail();
$moving_unique_id = $file->folder_id;
}
// Check access to requested item
Guardian::check_item_access([
$request->to_unique_id, $moving_unique_id
], $shared);
// Move item
Editor::move($request, $unique_id, $shared);
return response('Done!', 204);
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace App\Http\Controllers\FileFunctions;
use App\FileManagerFolder;
use App\Http\Tools\Demo;
use Illuminate\Support\Facades\Validator;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
class FavouriteController extends Controller
{
/**
* Add folder to user favourites
*
* @param Request $request
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function store(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'unique_id' => 'required|integer',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Get user & folder
$user = Auth::user();
$folder = FileManagerFolder::where('unique_id', $request->unique_id)->first();
if (is_demo($user->id)) {
return Demo::favourites($user);
}
// Check ownership
if ($folder->user_id !== $user->id) abort(403);
// Add folder to user favourites
$user->favourites()->syncWithoutDetaching($request->unique_id);
// Return updated favourites
return $user->favourites->makeHidden(['pivot']);
}
/**
* Remove folder from user favourites
*
* @param $unique_id
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function destroy($unique_id)
{
// Get user
$user = Auth::user();
if (is_demo($user->id)) {
return Demo::favourites($user);
}
// Remove folder from user favourites
$user->favourites()->detach($unique_id);
// Return updated favourites
return $user->favourites->makeHidden(['pivot']);
}
}

View File

@@ -0,0 +1,107 @@
<?php
namespace App\Http\Controllers\FileFunctions;
use App\Http\Requests\Share\CreateShareRequest;
use App\Http\Requests\Share\UpdateShareRequest;
use App\Http\Resources\ShareResource;
use Illuminate\Contracts\Routing\ResponseFactory;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use App\Share;
class ShareController extends Controller
{
/**
* Get shared record
*
* @return ShareResource
*/
public function show($token)
{
// Get record
$shared = Share::where(DB::raw('BINARY `token`'), $token)
->firstOrFail();
return new ShareResource($shared);
}
/**
* Generate file share link
*
* @param CreateShareRequest $request
* @return ShareResource
*/
public function store(CreateShareRequest $request)
{
do {
// Generate unique token
$token = Str::random(16);
} while (Share::where(DB::raw('BINARY `token`'), $token)->exists());
// Create shared options
$options = [
'password' => $request->has('password') ? Hash::make($request->password) : null,
'type' => $request->type === 'folder' ? 'folder' : 'file',
'protected' => $request->isPassword,
'permission' => $request->permission,
'item_id' => $request->unique_id,
'user_id' => Auth::id(),
'token' => $token,
];
// Return created shared record
return new ShareResource(Share::create($options));
}
/**
* Update sharing
*
* @param UpdateShareRequest $request
* @param $token
* @return ShareResource
*/
public function update(UpdateShareRequest $request, $token)
{
// Get sharing record
$shared = Share::where('token', $token)
->where('user_id', Auth::id())
->firstOrFail();
// Update sharing record
$shared->update([
'permission' => $request->permission,
'protected' => $request->protected,
'password' => $request->password ? Hash::make($request->password) : $shared->password,
]);
// Return shared record
return new ShareResource($shared);
}
/**
* Delete sharing item
*
* @param $token
* @return ResponseFactory|\Illuminate\Http\Response
* @throws \Exception
*/
public function destroy($token)
{
// Get sharing record
$shared = Share::where('token', $token)
->where('user_id', Auth::id())
->firstOrFail();
// Delete shared record
$shared->delete();
// Done
return response('Done!', 204);
}
}

View File

@@ -0,0 +1,115 @@
<?php
namespace App\Http\Controllers\FileFunctions;
use App\Http\Tools\Demo;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use App\FileManagerFolder;
use App\FileManagerFile;
class TrashController extends Controller
{
/**
* Empty user trash
*
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function clear()
{
// Get user id
$user_id = Auth::id();
if (is_demo($user_id)) {
return Demo::response_204();
}
// Get files and folders
$folders = FileManagerFolder::onlyTrashed()->where('user_id', $user_id)->get();
$files = FileManagerFile::onlyTrashed()->where('user_id', $user_id)->get();
// Force delete folder
$folders->each->forceDelete();
// Force delete files
foreach ($files as $file) {
// Delete file
Storage::delete('/file-manager/' . $file->basename);
// Delete thumbnail if exist
if ($file->thumbnail) Storage::delete('/file-manager/' . $file->getOriginal('thumbnail'));
// Delete file permanently
$file->forceDelete();
}
// Return response
return response('Done!', 204);
}
/**
* Restore item from trash
*
* @param Request $request
* @param $unique_id
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function restore(Request $request, $unique_id)
{
// Validate request
$validator = Validator::make($request->all(), [
'type' => 'required|string',
'to_home' => 'boolean',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Get user id
$user_id = Auth::id();
if (is_demo($user_id)) {
return Demo::response_204();
}
// Get folder
if ($request->type === 'folder') {
// Get folder
$item = FileManagerFolder::onlyTrashed()
->where('user_id', $user_id)
->where('unique_id', $unique_id)
->first();
// Restore item to home directory
if ($request->has('to_home') && $request->to_home) {
$item->parent_id = 0;
$item->save();
}
} else {
// Get item
$item = FileManagerFile::onlyTrashed()
->where('user_id', $user_id)
->where('unique_id', $unique_id)
->first();
// Restore item to home directory
if ($request->has('to_home') && $request->to_home) {
$item->folder_id = 0;
$item->save();
}
}
// Restore Item
$item->restore();
// Return response
return response('Done!', 204);
}
}

View File

@@ -1,620 +0,0 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cookie;
use Intervention\Image\ImageManagerStatic as Image;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\File;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use App\FileManagerFolder;
use App\FileManagerFile;
use Response;
class FileManagerController extends Controller
{
/**
* Get trashed files
*
* @param Request $request
* @return FileManagerFile[]|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Query\Builder[]|\Illuminate\Support\Collection
*/
public function trash()
{
// Get user id
$user_id = Auth::id();
// Get folders and files
$folders_trashed = FileManagerFolder::onlyTrashed()
->with(['trashed_folders'])
->where('user_id', $user_id)
->get(['parent_id', 'unique_id', 'name']);
$folders = FileManagerFolder::onlyTrashed()
->where('user_id', $user_id)
->whereIn('unique_id', filter_folders_ids($folders_trashed))
->get();
// Get files trashed
$files_trashed = FileManagerFile::onlyTrashed()
->where('user_id', $user_id)
->whereNotIn('folder_id', array_values(array_unique(recursiveFind($folders_trashed->toArray(), 'unique_id'))))
->get();
// Collect folders and files to single array
return collect([$folders, $files_trashed])->collapse();
}
/**
* Get directory with files
*
* @return \Illuminate\Support\Collection
*/
public function folder(Request $request, $unique_id)
{
// Get user
$user_id = Auth::id();
// Get folder trash items
if ($request->query('trash')) {
// Get folders and files
$folders = FileManagerFolder::onlyTrashed()
->where('user_id', $user_id)
->with('parent')
->where('parent_id', $unique_id)
->get();
$files = FileManagerFile::onlyTrashed()
->where('user_id', $user_id)
->with('parent')
->where('folder_id', $unique_id)
->get();
// Collect folders and files to single array
return collect([$folders, $files])->collapse();
}
// Get folders and files
$folders = FileManagerFolder::with('parent')
->where('user_id', $user_id)
->where('parent_id', $unique_id)
->get();
$files = FileManagerFile::with('parent')
->where('user_id', $user_id)
->where('folder_id', $unique_id)
->get();
// Collect folders and files to single array
return collect([$folders, $files])->collapse();
}
/**
* Search files
*
* @param Request $request
* @return \Illuminate\Database\Eloquent\Collection
*/
public function search(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'query' => 'required|string',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Get user
$user_id = Auth::id();
// Search files id db
$searched_files = FileManagerFile::search($request->input('query'))->where('user_id', $user_id)->get();
$searched_folders = FileManagerFolder::search($request->input('query'))->where('user_id', $user_id)->get();
// Collect folders and files to single array
return collect([$searched_folders, $searched_files])->collapse();
}
/**
* Create new folder
*
* @param Request $request
* @return array
*/
public function create_folder(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'parent_id' => 'required|integer',
'name' => 'string',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Get parent_id from request
$parent_id = $request->parent_id === 0 ? 0 : $request->parent_id;
// Create folder
$folder = FileManagerFolder::create([
'user_id' => Auth::id(),
'parent_id' => $parent_id,
'name' => $request->has('name') ? $request->input('name') : 'New Folder',
'type' => 'folder',
'unique_id' => $this->get_unique_id(),
]);
// Return new folder
return $folder;
}
/**
* Rename item name
*
* @param Request $request
* @return mixed
*/
public function rename_item(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'unique_id' => 'required|integer',
'name' => 'required|string',
'type' => 'required|string',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Get user id
$user_id = Auth::id();
// Update folder name
if ($request->type === 'folder') {
$item = FileManagerFolder::where('unique_id', $request->unique_id)
->where('user_id', $user_id)
->firstOrFail();
$item->name = $request->name;
$item->save();
} else {
$item = FileManagerFile::where('unique_id', $request->unique_id)
->where('user_id', $user_id)
->firstOrFail();
$item->name = $request->name;
$item->save();
}
// Return updated item
return $item;
}
/**
* Delete item
*
* @param Request $request
* @throws \Exception
*/
public function delete_item(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'unique_id' => 'required|integer',
'type' => 'required|string',
'force_delete' => 'required|boolean',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Get user id
$user = Auth::user();
// Delete folder
if ($request->type === 'folder') {
$item = FileManagerFolder::withTrashed()
->with('folders')
->where('user_id', $user->id)
->where('unique_id', $request->unique_id)
->first();
// Remove folder from user favourites
$user->favourites()->detach($request->unique_id);
foreach ($item->files as $file) {
if ($request->force_delete) {
// Delete file
Storage::disk('local')->delete('/file-manager/' . $file->basename);
// Delete thumbnail if exist
if (!is_null($file->thumbnail)) Storage::disk('local')->delete('/file-manager/' . $file->getOriginal('thumbnail'));
// Delete file permanently
$file->forceDelete();
} else {
// Delete file from visibility
$file->delete();
}
}
// Delete record
if ($request->force_delete) {
$item->forceDelete();
} else {
$item->delete();
}
}
if ($request->type === 'file' || $request->type === 'image') {
$item = FileManagerFile::withTrashed()
->where('user_id', $user->id)
->where('unique_id', $request->unique_id)
->first();
if ($request->force_delete) {
// Delete file
Storage::disk('local')->delete('/file-manager/' . $item->basename);
// Delete thumbnail if exist
if (!is_null($item->thumbnail)) Storage::disk('local')->delete('/file-manager/' . $item->thumbnail);
// Delete file permanently
$item->forceDelete();
} else {
// Delete file from visibility
$item->delete();
}
}
}
/**
* Empty user trash
*
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function empty_trash()
{
// Get user id
$user_id = Auth::id();
// Get files and folders
$folders = FileManagerFolder::onlyTrashed()->where('user_id', $user_id)->get();
$files = FileManagerFile::onlyTrashed()->where('user_id', $user_id)->get();
// Force delete every item
$folders->each->forceDelete();
$files->each->forceDelete();
// Return response
return response('Done!', 200);
}
/**
* Restore item from trash
*
* @param Request $request
*/
public function restore_item(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'unique_id' => 'required|integer',
'type' => 'required|string',
'to_home' => 'boolean',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Get user id
$user_id = Auth::id();
// Get folder
if ($request->type === 'folder') {
// Get folder
$item = FileManagerFolder::onlyTrashed()->where('user_id', $user_id)->where('unique_id', $request->unique_id)->first();
// Restore item to home directory
if ($request->has('to_home') && $request->to_home) {
$item->parent_id = 0;
$item->save();
}
}
// Get file
if ($request->type === 'file' || $request->type === 'image') {
// Get item
$item = FileManagerFile::onlyTrashed()->where('user_id', $user_id)->where('unique_id', $request->unique_id)->first();
// Restore item to home directory
if ($request->has('to_home') && $request->to_home) {
$item->folder_id = 0;
$item->save();
}
}
// Restore Item
$item->restore();
}
/**
* Delete Item
*
* @param Request $request
*/
public function delete_items(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'items' => 'required|json',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
foreach ($request->input('items') as $file) {
if ($file['type'] === 'file' || $file['type'] === 'image') {
$item = FileManagerFile::where('unique_id', $file['unique_id'])->first();
} else {
$item = FileManagerFolder::where('unique_id', $file['unique_id'])->first();
}
// Delete file
Storage::disk('local')->delete('/file-manager/' . $item->basename);
// Delete thumbnail if exist
if (!is_null($item->thumbnail)) {
Storage::disk('local')->delete('/file-manager/' . $item->thumbnail);
}
// Permanently delete file
$item->forceDelete();
}
}
/**
* Upload items
*
* @param Request $request
* @return array
*/
public function upload_item(Request $request)
{
// Check if user can upload
if (config('vuefilemanager.limit_storage_by_capacity') && user_storage_percentage() >= 100)
abort(423, 'You exceed your storage limit!');
// Validate request
$validator = Validator::make($request->all(), [
'parent_id' => 'required|integer',
'file' => 'required|file',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Get parent_id from request
$folder_id = $request->parent_id === 0 ? 0 : $request->parent_id;
$file = $request->file('file');
// File
$filename = Str::random() . '-' . str_replace(' ', '', $file->getClientOriginalName());
$filetype = 'file';
$thumbnail = null;
$filesize = $file->getSize();
$directory = 'file-manager';
// create directory if not exist
if (!Storage::disk('local')->exists($directory)) {
Storage::disk('local')->makeDirectory($directory);
}
// Store to disk
Storage::disk('local')->putFileAs($directory, $file, $filename, 'public');
// Create image thumbnail
if (substr($file->getMimeType(), 0, 5) == 'image') {
$filetype = 'image';
$thumbnail = 'thumbnail-' . $filename;
// Create intervention image
$image = Image::make($file->getRealPath());
$image->resize(256, null, function ($constraint) {
$constraint->aspectRatio();
})->save(null, 90);
// Store thumbnail to s3
Storage::disk('local')->put($directory . '/' . $thumbnail, $image);
}
// Store file
$new_file = FileManagerFile::create([
'user_id' => Auth::id(),
'name' => pathinfo($file->getClientOriginalName())['filename'],
'basename' => $filename,
'folder_id' => $folder_id,
'mimetype' => $file->getClientOriginalExtension(),
'filesize' => $filesize,
'type' => $filetype,
'thumbnail' => $thumbnail,
'unique_id' => $this->get_unique_id(),
]);
return $new_file;
}
/**
* Move item
*
* @param Request $request
*/
public function move_item(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'from_unique_id' => 'required|integer',
'to_unique_id' => 'required|integer',
'from_type' => 'required|string',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Get user id
$user_id = Auth::id();
if ($request->from_type === 'folder') {
// Move folder
$item = FileManagerFolder::where('user_id', $user_id)
->where('unique_id', $request->from_unique_id)
->firstOrFail();
$item->parent_id = $request->to_unique_id;
} else {
// Move file under new folder
$item = FileManagerFile::where('user_id', $user_id)
->where('unique_id', $request->from_unique_id)
->firstOrFail();
$item->folder_id = $request->to_unique_id;
}
$item->update();
}
/**
* Get file record
*
* @param $unique_id
* @return mixed
*/
public function get_file_detail($unique_id)
{
// Get user id
$user_id = Auth::id();
return FileManagerFile::where('user_id', $user_id)->where('unique_id', $unique_id)->firstOrFail();
}
/**
* Get file
*
* @param $filename
* @return mixed
*/
public function get_file($filename)
{
// Get user id
$user_id = Auth::id();
// Get file record
$file = FileManagerFile::withTrashed()
->where('user_id', $user_id)
->where('basename', $filename)
->firstOrFail();
// Get file path
$path = storage_path() . '/app/file-manager/' . $file->basename;
// Check if file exist
if (!File::exists($path)) abort(404);
$file = File::get($path);
$type = File::mimeType($path);
$size = File::size($path);
// Create response
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
$response->header("Content-Disposition", 'attachment; filename=' . $filename);
$response->header("Content-Length", $size);
return $response;
}
/**
* Get image thumbnail
*
* @param $filename
* @return mixed
*/
public function get_thumbnail($filename)
{
// Get user id
$user_id = Auth::id();
// Get file record
$file = FileManagerFile::withTrashed()
->where('user_id', $user_id)
->where('thumbnail', $filename)
->firstOrFail();
// Get file path
$path = storage_path() . '/app/file-manager/' . $file->getOriginal('thumbnail');
// Check if file exist
if (!File::exists($path)) abort(404);
$file = File::get($path);
$type = File::mimeType($path);
// Create response
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
return $response;
}
/**
* Get unique id
*
* @return int
*/
private function get_unique_id(): int
{
// Get files and folders
$folders = FileManagerFolder::withTrashed()->get();
$files = FileManagerFile::withTrashed()->get();
// Get last ids
$folders_unique = $folders->isEmpty() ? 0 : $folders->last()->unique_id;
$files_unique = $files->isEmpty() ? 0 : $files->last()->unique_id;
// Count new unique id
$unique_id = $folders_unique > $files_unique ? $folders_unique + 1 : $files_unique + 1;
return $unique_id;
}
}

View File

@@ -0,0 +1,405 @@
<?php
namespace App\Http\Controllers\Sharing;
use App\Http\Controllers\Controller;
use App\Http\Requests\Share\AuthenticateShareRequest;
use App\Http\Resources\ShareResource;
use App\Http\Tools\Guardian;
use http\Env\Response;
use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Collection;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use App\FileManagerFolder;
use App\FileManagerFile;
use App\User;
use App\Share;
use Illuminate\Support\Facades\Storage;
class FileSharingController extends Controller
{
/**
* Show page index and delete access_token & shared_token cookie
*
* @return Factory|\Illuminate\View\View
*/
public function index($token)
{
// Get shared token
$shared = Share::where(\DB::raw('BINARY `token`'), $token)
->first();
if (! $shared) {
return view("index");
}
// Delete old access_token if exist
Cookie::queue('shared_access_token', '', -1);
// Set cookies
if ($shared->protected) {
// Set shared token
Cookie::queue('shared_token', $token, 43200);
}
// Check if shared is image file and then show it
if ($shared->type === 'file' && ! $shared->protected) {
$image = FileManagerFile::where('user_id', $shared->user_id)
->where('type', 'image')
->where('unique_id', $shared->item_id)
->first();
if ($image) {
return $this->show_image($image);
}
}
// Return page index
return view("index");
}
/**
* Get image from storage and show it
*
* @param $file
* @return \Symfony\Component\HttpFoundation\StreamedResponse
*/
private function show_image($file)
{
// Format pretty filename
$file_pretty_name = $file->name . '.' . $file->mimetype;
// Get file path
$path = '/file-manager/' . $file->basename;
// Check if file exist
if (!Storage::exists($path)) abort(404);
$header = [
"Content-Type" => Storage::mimeType($path),
"Content-Length" => Storage::size($path),
"Accept-Ranges" => "bytes",
"Content-Range" => "bytes 0-600/" . Storage::size($path),
];
// Get file
return Storage::response($path, $file_pretty_name, $header);
}
/**
* Check Password for protected item
*
* @param AuthenticateShareRequest $request
* @param $token
* @return array
*/
public function authenticate(AuthenticateShareRequest $request, $token)
{
// Get sharing record
$shared = Share::where(DB::raw('BINARY `token`'), $token)->firstOrFail();
// Check password
if (!Hash::check($request->password, $shared->password)) {
abort(401, __('vuefilemanager.incorrect_password'));
}
// Get owner of shared content
$user = User::find($shared->user_id);
// Define scope
$scope = !is_null($shared->permission) ? $shared->permission : 'visitor';
// Generate token for visitor/editor
$access_token = $user->createToken('shared_access_token', [$scope])->accessToken;
// Return authorize token with shared options
return response(new ShareResource($shared), 200)
->cookie('shared_token', $shared->token, 43200)
->cookie('shared_access_token', $access_token, 43200);
}
/**
* Browse private folders
*
* @param Request $request
* @param $unique_id
* @return Collection
*/
public function get_private_folders(Request $request, $unique_id)
{
// Get sharing record
$shared = Share::where('token', $request->cookie('shared_token'))->firstOrFail();
// Check if user can get directory
Guardian::check_item_access($unique_id, $shared);
// Get files and folders
list($folders, $files) = $this->get_items($unique_id, $shared);
// Collect folders and files to single array
return collect([$folders, $files])->collapse();
}
/**
* Browse public folders
*
* @param $unique_id
* @return Collection
*/
public function get_public_folders($unique_id, $token)
{
// Get sharing record
$shared = Share::where(DB::raw('BINARY `token`'), $token)->firstOrFail();
// Abort if folder is protected
if ($shared->protected) {
abort(403, "Sorry, you don't have permission");
}
// Check if user can get directory
Guardian::check_item_access($unique_id, $shared);
// Get files and folders
list($folders, $files) = $this->get_items($unique_id, $shared);
// Set thumbnail links for public files
$files->map(function ($item) use ($token) {
$item->setPublicUrl($token);
});
// Collect folders and files to single array
return collect([$folders, $files])->collapse();
}
/**
* Get shared public file record
*
* @param $token
* @return mixed
*/
public function file_public($token)
{
// Get sharing record
$shared = Share::where(DB::raw('BINARY `token`'), $token)->firstOrFail();
// Abort if file is protected
if ($shared->protected) {
abort(403, "Sorry, you don't have permission");
}
// Get file
$file = FileManagerFile::where('user_id', $shared->user_id)
->where('unique_id', $shared->item_id)
->firstOrFail(['name', 'basename', 'thumbnail', 'type', 'filesize', 'mimetype']);
// Set urls
$file->setPublicUrl($token);
// Return record
return $file;
}
/**
* Get shared private file record
*
* @param $token
* @return mixed
*/
public function file_private(Request $request)
{
// Get sharing record
$shared = Share::where('token', $request->cookie('shared_token'))->firstOrFail();
// Return record
return FileManagerFile::where('user_id', $shared->user_id)
->where('unique_id', $shared->item_id)
->firstOrFail(['name', 'basename', 'thumbnail', 'type', 'filesize', 'mimetype']);
}
/**
* Get navigation tree
*
* @param Request $request
* @return array
*/
public function get_private_navigation_tree(Request $request)
{
// Get sharing record
$shared = get_shared($request->cookie('shared_token'));
// Check if user can get directory
Guardian::check_item_access($shared->item_id, $shared);
// Get folders
$folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('parent_id', $shared->item_id)
->where('user_id', $shared->user_id)
->get(['id', 'parent_id', 'unique_id', 'name']);
// Return folder tree
return [
[
'unique_id' => $shared->item_id,
'name' => __('vuefilemanager.home'),
'location' => 'public',
'folders' => $folders,
]
];
}
/**
* Get navigation tree
*
* @return array
*/
public function get_public_navigation_tree($token)
{
// Get sharing record
$shared = Share::where('token', $token)->firstOrFail();
// Check if user can get directory
Guardian::check_item_access($shared->item_id, $shared);
// Get folders
$folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('parent_id', $shared->item_id)
->where('user_id', $shared->user_id)
->get(['id', 'parent_id', 'unique_id', 'name']);
// Return folder tree
return [
[
'unique_id' => $shared->item_id,
'name' => __('vuefilemanager.home'),
'location' => 'public',
'folders' => $folders,
]
];
}
/**
* Search private files
*
* @param Request $request
* @param $token
* @return Collection
*/
public function search_private(Request $request)
{
// Get shared
$shared = get_shared($request->cookie('shared_token'));
// Search files id db
$searched_files = FileManagerFile::search($request->input('query'))
->where('user_id', $shared->user_id)
->get();
$searched_folders = FileManagerFolder::search($request->input('query'))
->where('user_id', $shared->user_id)
->get();
// Get all children content
$foldersIds = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('user_id', $shared->user_id)
->where('parent_id', $shared->item_id)
->get();
// Get accessible folders
$accessible_folder_ids = Arr::flatten([filter_folders_ids($foldersIds), $shared->item_id]);
// Filter files to only accessible files
$files = $searched_files->filter(function ($file) use ($accessible_folder_ids) {
return in_array($file->folder_id, $accessible_folder_ids);
});
// Filter folders to only accessible folders
$folders = $searched_folders->filter(function ($folder) use ($accessible_folder_ids) {
return in_array($folder->unique_id, $accessible_folder_ids);
});
// Collect folders and files to single array
return collect([$folders, $files])->collapse();
}
/**
* Search public files
*
* @param Request $request
* @param $token
* @return Collection
*/
public function search_public(Request $request, $token)
{
// Get shared
$shared = get_shared($token);
// Abort if folder is protected
if ($shared->protected) {
abort(403, "Sorry, you don't have permission");
}
// Search files id db
$searched_files = FileManagerFile::search($request->input('query'))
->where('user_id', $shared->user_id)
->get();
$searched_folders = FileManagerFolder::search($request->input('query'))
->where('user_id', $shared->user_id)
->get();
// Get all children content
$foldersIds = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('user_id', $shared->user_id)
->where('parent_id', $shared->item_id)
->get();
// Get accessible folders
$accessible_folder_ids = Arr::flatten([filter_folders_ids($foldersIds), $shared->item_id]);
// Filter files
$files = $searched_files->filter(function ($file) use ($accessible_folder_ids, $token) {
// Set public urls
$file->setPublicUrl($token);
// check if item is in accessible folders
return in_array($file->folder_id, $accessible_folder_ids);
});
// Filter folders
$folders = $searched_folders->filter(function ($folder) use ($accessible_folder_ids) {
// check if item is in accessible folders
return in_array($folder->unique_id, $accessible_folder_ids);
});
// Collect folders and files to single array
return collect([$folders, $files])->collapse();
}
/**
* Get folders and files
*
* @param $unique_id
* @param $shared
* @return array
*/
private function get_items($unique_id, $shared): array
{
$folders = FileManagerFolder::where('user_id', $shared->user_id)
->where('parent_id', $unique_id)
->get();
$files = FileManagerFile::where('user_id', $shared->user_id)
->where('folder_id', $unique_id)
->get();
return [$folders, $files];
}
}

View File

@@ -0,0 +1,134 @@
<?php
namespace App\Http\Controllers\User;
use App\FileManagerFile;
use App\FileManagerFolder;
use App\Http\Resources\StorageDetailResource;
use App\Http\Resources\UserStorageResource;
use App\Http\Tools\Demo;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Support\Facades\Validator;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Http\Request;
use ByteUnits\Metric;
use App\User;
class AccountController extends Controller
{
/**
* Get all user data to frontend
*
* @return array
*/
public function user()
{
// Get User
$user = User::with(['favourites', 'latest_uploads'])
->where('id', Auth::id())
->first();
// Get folder tree
$tree = FileManagerFolder::with(['folders.shared', 'shared:token,id,item_id,permission,protected'])
->where('parent_id', 0)
->where('user_id', $user->id)
->get();
return [
'user' => $user->only(['name', 'email', 'avatar', 'role']),
'favourites' => $user->favourites->makeHidden(['pivot']),
'tree' => $tree,
'storage' => [
'used' => Metric::bytes($user->used_capacity)->format(),
'capacity' => format_gigabytes($user->settings->storage_capacity),
'percentage' => get_storage_fill_percentage($user->used_capacity, $user->settings->storage_capacity),
],
];
}
/**
* Get storage details
*
* @return UserStorageResource
*/
public function storage()
{
return new UserStorageResource(Auth::user());
}
/**
* Update user profile
*
* @param Request $request
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function update_profile(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'avatar' => 'file',
'name' => 'string',
'value' => 'string',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Get user
$user = Auth::user();
// Check if is demo
if (is_demo($user->id)) {
return Demo::response_204();
}
// Check role
if ($request->has('role')) abort(403);
// Update data
if ($request->hasFile('avatar')) {
// Update avatar
$avatar = store_avatar($request->file('avatar'), 'avatars');
// Update data
$user->update(['avatar' => $avatar]);
} else {
// Update text data
$user->update(make_single_input($request));
}
return response('Saved!', 204);
}
/**
* Change user password
*
* @param Request $request
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function change_password(Request $request)
{
// Validate request
$request->validate([
'password' => ['required', 'string', 'min:6', 'confirmed'],
]);
// Get user
$user = Auth::user();
if (is_demo($user->id)) {
return Demo::response_204();
}
// Change and store new password
$user->password = Hash::make($request->input('password'));
$user->save();
return response('Changed!', 204);
}
}

View File

@@ -1,153 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\User;
use ByteUnits\Metric;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Hash;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
class UserAccountController extends Controller
{
/**
* Get all user data to frontend
*
* @return array|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
*/
public function user()
{
$user_id = Auth::id();
// Get User
$user = User::with(['favourites', 'latest_uploads'])->where('id', $user_id)->first();
return [
'user' => $user->only(['name', 'email', 'avatar']),
'favourites' => $user->favourites->makeHidden(['pivot']),
'latest_uploads' => $user->latest_uploads->makeHidden(['user_id', 'basename']),
'storage' => [
'used' => Metric::bytes($user->used_capacity)->format(),
'capacity' => format_gigabytes(config('vuefilemanager.user_storage_capacity')),
'percentage' => get_storage_fill_percentage($user->used_capacity, config('vuefilemanager.user_storage_capacity')),
],
];
}
/**
* Update user profile
*
* @param Request $request
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function update_profile(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'avatar' => 'file',
'_method' => 'string',
'name' => 'string',
'value' => 'string',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Get user
$user = Auth::user();
if ($request->hasFile('avatar')) {
// Update avatar
$avatar = store_avatar($request->file('avatar'), 'avatars');
// Update data
$user->update(['avatar' => $avatar]);
} else {
// Update text data
$user->update(make_single_input($request));
}
return response('Saved!', 200);
}
/**
* Change user password
*
* @param Request $request
* @return array
*/
public function change_password(Request $request)
{
// Validate request
$request->validate([
'password' => ['required', 'string', 'min:6', 'confirmed'],
]);
// Get user
$user = Auth::user();
// Change and store new password
$user->password = Hash::make($request->input('password'));
$user->save();
}
/**
* Add folder to user favourites
*
* @param Request $request
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function add_to_favourites(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'unique_id' => 'required|integer',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Get user
$user = Auth::user();
// Add folder to user favourites
$user->favourites()->attach($request->unique_id);
// Return updated favourites
return $user->favourites->makeHidden(['pivot']);
}
/**
* Remove folder from user favourites
*
* @param Request $request
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function remove_from_favourites(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'unique_id' => 'required|integer',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Get user
$user = Auth::user();
// Remove folder from user favourites
$user->favourites()->detach($request->unique_id);
// Return updated favourites
return $user->favourites->makeHidden(['pivot']);
}
}

View File

@@ -2,7 +2,10 @@
namespace App\Http;
use App\Http\Middleware\AdminCheck;
use App\Http\Middleware\CookieAuth;
use App\Http\Middleware\LastCheck;
use App\Http\Middleware\SharedAuth;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
@@ -40,6 +43,7 @@ class Kernel extends HttpKernel
],
'api' => [
\App\Http\Middleware\EncryptCookies::class,
//'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
@@ -53,6 +57,9 @@ class Kernel extends HttpKernel
* @var array
*/
protected $routeMiddleware = [
'auth.master' => CookieAuth::class,
'auth.shared' => SharedAuth::class,
'auth.admin' => AdminCheck::class,
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
@@ -63,7 +70,8 @@ class Kernel extends HttpKernel
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'auth.cookie' => CookieAuth::class,
'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,
];
/**
@@ -77,6 +85,7 @@ class Kernel extends HttpKernel
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
CookieAuth::class,
SharedAuth::class,
\App\Http\Middleware\Authenticate::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Gate;
class AdminCheck
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// Check if user have access to administration settings
if ( ! Gate::allows('admin-settings')) {
abort(403, 'You don\'t have access for this operation!');
}
return $next($request);
}
}

View File

@@ -3,6 +3,7 @@
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class CookieAuth
{
@@ -16,14 +17,12 @@ class CookieAuth
public function handle($request, Closure $next)
{
if (!$request->bearerToken()) {
if ($request->hasCookie('token')) {
if ($request->hasCookie('access_token')) {
$token = $request->cookie('token');
$access_token = $request->cookie('access_token');
$request->headers->add(['Authorization' => 'Bearer ' . $token]);
$request->headers->add(['Authorization' => 'Bearer ' . $access_token]);
} else {
abort(401);
}
}
return $next($request);

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Http\Middleware;
use Closure;
class SharedAuth
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (!$request->bearerToken()) {
if ($request->hasCookie('shared_access_token')) {
$shared_access_token = $request->cookie('shared_access_token');
$request->headers->add(['Authorization' => 'Bearer ' . $shared_access_token]);
}
}
return $next($request);
}
}

View File

@@ -19,6 +19,6 @@ class VerifyCsrfToken extends Middleware
* @var array
*/
protected $except = [
//
'/deploy',
];
}

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests\Admin;
use Illuminate\Foundation\Http\FormRequest;
class ChangeRoleRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'attributes' => 'required|array',
'attributes.role' => 'required|string'
];
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests\Admin;
use Illuminate\Foundation\Http\FormRequest;
class ChangeStorageCapacityRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'attributes' => 'required|array',
'attributes.storage_capacity' => 'required|digits_between:1,9'
];
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace App\Http\Requests\Admin;
use Illuminate\Foundation\Http\FormRequest;
class CreateUserByAdmin extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
'name' => 'required|string|max:255',
'storage_capacity' => 'required|digits_between:1,9',
'role' => 'required|string',
'avatar' => 'sometimes|file',
];
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Http\Requests\Admin;
use Illuminate\Foundation\Http\FormRequest;
class DeleteUserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string|max:255',
];
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Http\Requests\Auth;
use Illuminate\Foundation\Http\FormRequest;
class CheckAccountRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'email' => 'required|string|email',
];
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Http\Requests\FileBrowser;
use Illuminate\Foundation\Http\FormRequest;
class SearchRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'query' => 'required|string',
];
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Http\Requests\FileFunctions;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class CreateFolderRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'parent_id' => 'required|integer',
'name' => 'string',
];
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Http\Requests\FileFunctions;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class DeleteItemRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'type' => 'required|string',
'force_delete' => 'required|boolean',
];
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Http\Requests\FileFunctions;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class MoveItemRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'to_unique_id' => 'required|integer',
'from_type' => 'required|string',
];
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Http\Requests\FileFunctions;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class RenameItemRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string',
'type' => 'required|string',
];
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Http\Requests\FileFunctions;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class UploadRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'parent_id' => 'required|integer',
'file' => 'required|file',
];
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Http\Requests\Share;
use Illuminate\Foundation\Http\FormRequest;
class AuthenticateShareRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'password' => 'required|string',
];
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace App\Http\Requests\Share;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class CreateShareRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return Auth::check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'isPassword' => 'required|boolean',
'unique_id' => 'required|integer',
'type' => 'required|string',
'permission' => 'string',
'password' => 'string',
];
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Http\Requests\Share;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class UpdateShareRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return Auth::check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'protected' => 'required|boolean',
'permission' => 'nullable|string',
'password' => 'string',
];
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class ShareResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => [
'id' => (string)$this->id,
'type' => 'shares',
'attributes' => [
'permission' => $this->permission,
'protected' => $this->protected,
'item_id' => $this->item_id,
'token' => $this->token,
'link' => $this->link,
'type' => $this->type,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
]
]
];
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace App\Http\Resources;
use Faker\Factory;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
// Faker only for demo purpose
$faker = Factory::create();
return [
'data' => [
'id' => (string)$this->id,
'type' => 'user',
'attributes' => [
'name' => env('APP_DEMO') ? $faker->name : $this->name,
'email' => env('APP_DEMO') ? $faker->email : $this->email,
'avatar' => $this->avatar,
'role' => $this->role,
'storage' => $this->storage,
'created_at_formatted' => format_date($this->created_at, '%d. %B. %Y'),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
]
]
];
}
}

View File

@@ -0,0 +1,89 @@
<?php
namespace App\Http\Resources;
use App\FileManagerFile;
use ByteUnits\Metric;
use Illuminate\Http\Resources\Json\JsonResource;
class UserStorageResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
$document_mimetypes = [
'pdf', 'numbers', 'xlsx', 'xls', 'txt', 'md', 'rtf', 'pptx', 'ppt', 'odt', 'ods', 'odp', 'epub', 'docx', 'doc', 'csv', 'pages'
];
// Get all images
$images = FileManagerFile::where('user_id', $this->id)
->where('type', 'image')->get()->map(function ($item) {
return (int)$item->getOriginal('filesize');
})->sum();
// Get all audios
$audios = FileManagerFile::where('user_id', $this->id)
->where('type', 'audio')->get()->map(function ($item) {
return (int)$item->getOriginal('filesize');
})->sum();
// Get all videos
$videos = FileManagerFile::where('user_id', $this->id)
->where('type', 'video')->get()->map(function ($item) {
return (int)$item->getOriginal('filesize');
})->sum();
// Get all documents
$documents = FileManagerFile::where('user_id', $this->id)
->whereIn('mimetype', $document_mimetypes)->get()->map(function ($item) {
return (int)$item->getOriginal('filesize');
})->sum();
// Get all other files
$others = FileManagerFile::where('user_id', $this->id)
->whereNotIn('mimetype', $document_mimetypes)
->whereNotIn('type', ['audio', 'video', 'image'])
->get()->map(function ($item) {
return (int)$item->getOriginal('filesize');
})->sum();
return [
'data' => [
'id' => (string)$this->id,
'type' => 'user-storage',
'attributes' => [
'used' => Metric::bytes($this->used_capacity)->format(),
'capacity' => format_gigabytes($this->settings->storage_capacity),
'percentage' => (float)get_storage_fill_percentage($this->used_capacity, $this->settings->storage_capacity),
],
'meta' => [
'images' => [
'used' => Metric::bytes($images)->format(),
'percentage' => (float)get_storage_fill_percentage($images, $this->settings->storage_capacity),
],
'audios' => [
'used' => Metric::bytes($audios)->format(),
'percentage' => (float)get_storage_fill_percentage($audios, $this->settings->storage_capacity),
],
'videos' => [
'used' => Metric::bytes($videos)->format(),
'percentage' => (float)get_storage_fill_percentage($videos, $this->settings->storage_capacity),
],
'documents' => [
'used' => Metric::bytes($documents)->format(),
'percentage' => (float)get_storage_fill_percentage($documents, $this->settings->storage_capacity),
],
'others' => [
'used' => Metric::bytes($others)->format(),
'percentage' => (float)get_storage_fill_percentage($others, $this->settings->storage_capacity),
],
]
]
];
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class UsersCollection extends ResourceCollection
{
public $collects = UserResource::class;
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => $this->collection,
];
}
}

143
app/Http/Tools/Demo.php Normal file
View File

@@ -0,0 +1,143 @@
<?php
namespace App\Http\Tools;
use App;
use App\Share;
use App\FileManagerFile;
use App\FileManagerFolder;
use App\Http\Requests\FileFunctions\RenameItemRequest;
use App\User;
use ByteUnits\Metric;
use Carbon\Carbon;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\ImageManagerStatic as Image;
class Demo
{
/**
* Create new directory
*
* @param $request
* @return array
* @throws \Exception
*/
public static function create_folder($request)
{
// Get variables
$user_scope = $request->user() ? $request->user()->token()->scopes[0] : 'editor';
$name = $request->has('name') ? $request->input('name') : 'New Folder';
return [
'user_id' => 1,
'id' => random_int(1000, 9999),
'parent_id' => random_int(1000, 9999),
'name' => $name,
'type' => 'folder',
'unique_id' => random_int(1000, 9999),
'user_scope' => $user_scope,
'items' => '0',
'updated_at' => Carbon::now()->format('j M Y \a\t H:i'),
'created_at' => Carbon::now()->format('j M Y \a\t H:i'),
];
}
/**
* Rename item name
*
* @param RenameItemRequest $request
* @param $unique_id
* @return mixed
*/
public static function rename_item($request, $unique_id)
{
// Get item
if ($request->type === 'folder') {
$item = FileManagerFolder::where('unique_id', $unique_id)
->where('user_id', 1)
->first();
} else {
$item = FileManagerFile::where('unique_id', $unique_id)
->where('user_id', 1)
->first();
}
if ($item) {
$item->name = $request->name;
return $item;
} else {
return [
'unique_id' => $request->unique_id,
'name' => $request->name,
'type' => $request->type,
];
}
}
/**
* Upload file
*
* @param $request
* @return array
* @throws \Exception
*/
public static function upload($request)
{
// Get user data
$user_scope = $request->user() ? $request->user()->token()->scopes[0] : 'editor';
// File
$file = $request->file('file');
$filename = Str::random() . '-' . str_replace(' ', '', $file->getClientOriginalName());
$thumbnail = null;
$filesize = $file->getSize();
$filetype = get_file_type($file);
return [
'id' => random_int(1000, 9999),
'unique_id' => random_int(1000, 9999),
'folder_id' => $request->parent_id,
'thumbnail' => 'data:' . $request->file('file')->getMimeType() . ';base64, ' . base64_encode(file_get_contents($request->file('file'))),
'name' => $file->getClientOriginalName(),
'basename' => $filename,
'mimetype' => $file->getClientOriginalExtension(),
'filesize' => Metric::bytes($filesize)->format(),
'type' => $filetype,
'file_url' => 'https://vuefilemanager.hi5ve.digital/assets/vue-file-manager-preview.jpg',
'user_scope' => $user_scope,
'created_at' => Carbon::now()->format('j M Y \a\t H:i'),
'updated_at' => Carbon::now()->format('j M Y \a\t H:i'),
];
}
/**
* Return 204 status
*
* @return ResponseFactory|\Illuminate\Http\Response
*/
public static function response_204() {
return response('Done!', 204);
}
/**
* Return 204 status
*
* @return ResponseFactory|\Illuminate\Http\Response
*/
public static function favourites($user) {
return $user->favourites->makeHidden(['pivot']);
}
}

294
app/Http/Tools/Editor.php Normal file
View File

@@ -0,0 +1,294 @@
<?php
namespace App\Http\Tools;
use App;
use App\Share;
use App\FileManagerFile;
use App\FileManagerFolder;
use App\Http\Requests\FileFunctions\RenameItemRequest;
use App\User;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\ImageManagerStatic as Image;
class Editor
{
/**
* Create new directory
*
* @param $request
* @param null $shared
* @return FileManagerFolder|\Illuminate\Database\Eloquent\Model
*/
public static function create_folder($request, $shared = null)
{
// Get variables
$user_scope = is_null($shared) ? $request->user()->token()->scopes[0] : 'editor';
$name = $request->has('name') ? $request->input('name') : 'New Folder';
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
// Create folder
$folder = FileManagerFolder::create([
'parent_id' => $request->parent_id,
'unique_id' => get_unique_id(),
'user_scope' => $user_scope,
'user_id' => $user_id,
'type' => 'folder',
'name' => $name,
]);
// Return new folder
return $folder;
}
/**
* Rename item name
*
* @param RenameItemRequest $request
* @param $unique_id
* @param null $shared
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
* @throws \Exception
*/
public static function rename_item($request, $unique_id, $shared = null)
{
// Get user id
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
// Get item
$item = get_item($request->type, $unique_id, $user_id);
// Rename item
$item->update([
'name' => $request->name
]);
// Return updated item
return $item;
}
/**
* Delete file or folder
*
* @param $request
* @param $unique_id
* @param null $shared
* @throws \Exception
*/
public static function delete_item($request, $unique_id, $shared = null)
{
// Get user id
$user = is_null($shared) ? Auth::user() : User::findOrFail($shared->user_id);
// Delete folder
if ($request->type === 'folder') {
// Get folder
$folder = FileManagerFolder::withTrashed()
->with(['folders'])
->where('user_id', $user->id)
->where('unique_id', $unique_id)
->first();
// Get folder shared record
$shared = Share::where('user_id', $user->id)
->where('type', '=', 'folder')
->where('item_id', $unique_id)
->first();
// Delete folder shared record
if ($shared) {
$shared->delete();
}
// Force delete children files
if ($request->force_delete) {
// Get children folder ids
$child_folders = filter_folders_ids($folder->trashed_folders, 'unique_id');
// Get children files
$files = FileManagerFile::onlyTrashed()
->where('user_id', $user->id)
->whereIn('folder_id', Arr::flatten([$unique_id, $child_folders]))
->get();
// Remove all children files
foreach ($files as $file) {
// Delete file
Storage::delete('/file-manager/' . $file->basename);
// Delete thumbnail if exist
if (!is_null($file->thumbnail)) Storage::delete('/file-manager/' . $file->getOriginal('thumbnail'));
// Delete file permanently
$file->forceDelete();
}
// Delete folder record
$folder->forceDelete();
}
// Soft delete items
if (!$request->force_delete) {
// Remove folder from user favourites
$user->favourites()->detach($unique_id);
// Soft delete folder record
$folder->delete();
}
}
// Delete item
if ($request->type !== 'folder') {
// Get file
$file = FileManagerFile::withTrashed()
->where('user_id', $user->id)
->where('unique_id', $unique_id)
->first();
// Get folder shared record
$shared = Share::where('user_id', $user->id)
->where('type', '=', 'file')
->where('item_id', $unique_id)
->first();
// Delete file shared record
if ($shared) {
$shared->delete();
}
// Force delete file
if ($request->force_delete) {
// Delete file
Storage::delete('/file-manager/' . $file->basename);
// Delete thumbnail if exist
if ($file->thumbnail) Storage::delete('/file-manager/' . $file->getOriginal('thumbnail'));
// Delete file permanently
$file->forceDelete();
}
// Soft delete file
if (!$request->force_delete) {
// Soft delete file
$file->delete();
}
}
}
/**
* Upload file
*
* @param $request
* @param null $shared
* @return FileManagerFile|\Illuminate\Database\Eloquent\Model
* @throws \Exception
*/
public static function upload($request, $shared = null)
{
// Get user data
$user_scope = is_null($shared) ? $request->user()->token()->scopes[0] : 'editor';
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
// Get parent_id from request
$folder_id = $request->parent_id === 0 ? 0 : $request->parent_id;
$file = $request->file('file');
// File
$filename = Str::random() . '-' . str_replace(' ', '', $file->getClientOriginalName());
$filetype = get_file_type($file);
$filesize = $file->getSize();
$directory = 'file-manager';
$thumbnail = null;
// create directory if not exist
if (!Storage::exists($directory)) {
Storage::makeDirectory($directory);
}
// Store to disk
Storage::putFileAs($directory, $file, $filename, 'private');
// Create image thumbnail
if ($filetype == 'image') {
// Get thumbnail name
$thumbnail = 'thumbnail-' . $filename;
// Create intervention image
$image = Image::make($file->getRealPath())->orientate();
// Resize image
$image->resize(564, null, function ($constraint) {
$constraint->aspectRatio();
})->stream();
// Store thumbnail to disk
Storage::put($directory . '/' . $thumbnail, $image);
}
// Store file
$options = [
'name' => pathinfo($file->getClientOriginalName())['filename'],
'mimetype' => $file->getClientOriginalExtension(),
'unique_id' => get_unique_id(),
'user_scope' => $user_scope,
'folder_id' => $folder_id,
'thumbnail' => $thumbnail,
'basename' => $filename,
'filesize' => $filesize,
'type' => $filetype,
'user_id' => $user_id,
];
// Return new file
return FileManagerFile::create($options);
}
/**
* Move folder or file to new location
*
* @param $request
* @param $unique_id
* @param null $shared
*/
public static function move($request, $unique_id, $shared = null)
{
// Get user id
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
if ($request->from_type === 'folder') {
// Move folder
$item = FileManagerFolder::where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
$item->update([
'parent_id' => $request->to_unique_id
]);
} else {
// Move file under new folder
$item = FileManagerFile::where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
$item->update([
'folder_id' => $request->to_unique_id
]);
}
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Http\Tools;
use App;
use App\FileManagerFolder;
use Illuminate\Support\Arr;
class Guardian
{
/**
* Check access to requested directory
*
* @param integer|array $requested_id
* @param string $shared Shared record detail
*/
public static function check_item_access($requested_id, $shared)
{
// Get all children folders
$foldersIds = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('user_id', $shared->user_id)
->where('parent_id', $shared->item_id)
->get();
// Get all authorized parent folders by shared folder as root of tree
$accessible_folder_ids = Arr::flatten([filter_folders_ids($foldersIds), $shared->item_id]);
// Check user access
if ( is_array($requested_id) ) {
foreach ($requested_id as $id) {
if (!in_array($id, $accessible_folder_ids))
abort(403);
}
}
if (! is_array($requested_id)) {
if (! in_array($requested_id, $accessible_folder_ids))
abort(403);
}
}
}

View File

@@ -1,10 +1,125 @@
<?php
use App\FileManagerFile;
use App\FileManagerFolder;
use App\Share;
use ByteUnits\Metric;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\ImageManagerStatic as Image;
/**
* Get app version from config
*
* @return \Illuminate\Config\Repository|mixed
*/
function get_storage() {
return env('FILESYSTEM_DRIVER');
}
/**
* Check if is running AWS s3 as storage
*
* @return bool
*/
function is_storage_driver($driver) {
if (is_array($driver)) {
return in_array(env('FILESYSTEM_DRIVER'), $driver);
}
return env('FILESYSTEM_DRIVER') === $driver;
}
/**
* Get app version from config
*
* @return \Illuminate\Config\Repository|mixed
*/
function get_version() {
return config('vuefilemanager.version');
}
/**
* Check if is demo
*
* @return mixed
*/
function is_demo($user_id) {
return env('APP_DEMO', false) && $user_id === 1;
}
/**
* Get folder or file item
*
* @param $type
* @param $unique_id
* @param $user_id
* @return \Illuminate\Database\Eloquent\Builder|Model
*/
function get_item($type, $unique_id, $user_id) {
if ($type === 'folder') {
// Return folder item
return FileManagerFolder::where('unique_id', $unique_id)
->where('user_id', $user_id)
->firstOrFail();
}
// Return file item
return FileManagerFile::where('unique_id', $unique_id)
->where('user_id', $user_id)
->firstOrFail();
}
/**
* Get shared token
*
* @param $token
* @return \Illuminate\Database\Eloquent\Builder|Model
*/
function get_shared($token) {
return Share::where(DB::raw('BINARY `token`'), $token)
->firstOrFail();
}
/**
* Check if shared permission is editor
*
* @param $shared
* @return bool
*/
function is_editor($shared) {
return $shared->permission === 'editor';
}
/**
* Get unique id
*
* @return int
*/
function get_unique_id(): int
{
// Get files and folders
$folders = FileManagerFolder::withTrashed()->get();
$files = FileManagerFile::withTrashed()->get();
// Get last ids
$folders_unique = $folders->isEmpty() ? 0 : $folders->last()->unique_id;
$files_unique = $files->isEmpty() ? 0 : $files->last()->unique_id;
// Count new unique id
$unique_id = $folders_unique > $files_unique ? $folders_unique + 1 : $files_unique + 1;
return $unique_id;
}
/**
* Store user avatar to storage
@@ -19,16 +134,19 @@ function store_avatar($image, $path)
$path = check_directory($path);
// Store avatar
$image_path = $path . '/' . Str::random(8) . '-' . $image->getClientOriginalName();
$image_path = Str::random(8) . '-' . $image->getClientOriginalName();
// Create intervention image
$img = Image::make($image->getRealPath());
// Generate thumbnail
$img->fit('150', '150')->save(storage_path() . "/app/" . $image_path, 90);
$img->fit('150', '150')->stream();
// Store thumbnail to disk
Storage::put($path . '/' . $image_path, $img);
// Return path to image
return $image_path;
return $path . '/' . $image_path;
}
/**
@@ -54,7 +172,6 @@ function check_directory($directory)
*/
function make_single_input($request)
{
// Create container
$data = [];
@@ -71,9 +188,9 @@ function make_single_input($request)
* @param $gigabytes
* @return string
*/
function format_gigabytes($megabytes)
function format_gigabytes($gigabytes)
{
return Metric::megabytes($megabytes)->format();
return Metric::gigabytes($gigabytes)->format();
}
/**
@@ -86,7 +203,7 @@ function format_gigabytes($megabytes)
function get_storage_fill_percentage($used, $capacity)
{
// Format gigabytes to bytes
$total = intval(Metric::megabytes($capacity)->numberOfBytes());
$total = intval(Metric::gigabytes($capacity)->numberOfBytes());
// Count progress
$progress = ($used * 100) / $total;
@@ -100,11 +217,11 @@ function get_storage_fill_percentage($used, $capacity)
*
* @return string
*/
function user_storage_percentage() {
function user_storage_percentage()
{
$user = Auth::user();
$user = \Illuminate\Support\Facades\Auth::user();
return get_storage_fill_percentage($user->used_capacity, config('vuefilemanager.user_storage_capacity'));
return get_storage_fill_percentage($user->used_capacity, $user->settings->storage_capacity);
}
/**
@@ -152,9 +269,49 @@ function appeared_once($arr)
* @param $folders
* @return array
*/
function filter_folders_ids($folders)
function filter_folders_ids($folders, $by_column = 'unique_id')
{
$folder_unique_ids = recursiveFind($folders->toArray(), 'unique_id');
$folder_unique_ids = recursiveFind($folders->toArray(), $by_column);
return appeared_once($folder_unique_ids);
}
/**
* Format localized date
*
* @param $date
* @param string $format
* @return string
*/
function format_date($date, $format = '%d. %B. %Y, %H:%M')
{
$start = Carbon::parse($date);
return $start->formatLocalized($format);
}
/**
* Get file type from mimetype
*
* @param $file
* @return string
*/
function get_file_type($file)
{
// Get mimetype from file
$mimetype = explode('/', $file->getMimeType());
switch ($mimetype[0]) {
case 'image':
return 'image';
break;
case 'video':
return 'video';
break;
case 'audio':
return 'audio';
break;
default:
return 'file';
}
}

View File

@@ -1,33 +0,0 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class TestMail extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->from('peterpapp@makingcg.com')->view('welcome');
}
}

View File

@@ -43,10 +43,12 @@ class ResetPassword extends Notification
$reset_url = url('/create-new-password?token=' . $this->token);
return (new MailMessage)
->subject('Reset password for your account on ' . env('APP_NAME'))
->line('You are receiving this email because we received a password reset request for your account.')
->action('Reset Password', $reset_url)
->line('If you did not request a password reset, no further action is required.');
->subject(__('vuefilemanager.reset_password_subject') . config('vuefilemanager.app_name'))
->greeting(__('vuefilemanager.reset_password_greeting'))
->line(__('vuefilemanager.reset_password_line_1'))
->action(__('vuefilemanager.reset_password_action'), $reset_url)
->line(__('vuefilemanager.reset_password_line_2'))
->salutation(__('vuefilemanager.salutation') . ', ' . config('vuefilemanager.app_name'));
}
/**

View File

@@ -2,6 +2,8 @@
namespace App\Providers;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
@@ -23,6 +25,11 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot()
{
//
Schema::defaultStringLength(191);
$get_time_locale = App::getLocale() . '_' . mb_strtoupper(App::getLocale());
// Set locale for carbon dates
setlocale(LC_TIME, $get_time_locale);
}
}

View File

@@ -26,6 +26,23 @@ class AuthServiceProvider extends ServiceProvider
{
$this->registerPolicies();
// Define admin settings gate
Gate::define('admin-settings', function ($user) {
return $user->role === 'admin';
});
Passport::routes();
Passport::tokensCan([
'master' => 'Master',
'editor' => 'Editor',
'visitor' => 'Visitor',
]);
Passport::setDefaultScope([
'master',
'editor',
'visitor',
]);
}
}

51
app/Share.php Normal file
View File

@@ -0,0 +1,51 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* App\Share
*
* @property int $id
* @property int $user_id
* @property string $token
* @property int $item_id
* @property string $type
* @property string|null $permission
* @property int $protected
* @property string|null $password
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read string $link
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share query()
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share whereItemId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share wherePassword($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share wherePermission($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share whereProtected($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share whereToken($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share whereType($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share whereUserId($value)
* @mixin \Eloquent
*/
class Share extends Model
{
protected $guarded = ['id'];
protected $appends = ['link'];
/**
* Generate share link
*
* @return string
*/
public function getLinkAttribute() {
return url('/shared', ['token' => $this->attributes['token']]);
}
}

View File

@@ -12,6 +12,47 @@ use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Notification;
use Laravel\Passport\HasApiTokens;
/**
* App\User
*
* @property int $id
* @property string $name
* @property string $email
* @property \Illuminate\Support\Carbon|null $email_verified_at
* @property string $password
* @property \Illuminate\Contracts\Routing\UrlGenerator|string $avatar
* @property string|null $remember_token
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Illuminate\Database\Eloquent\Collection|\Laravel\Passport\Client[] $clients
* @property-read int|null $clients_count
* @property-read \Illuminate\Database\Eloquent\Collection|\App\FileManagerFolder[] $favourites
* @property-read int|null $favourites_count
* @property-read \Illuminate\Database\Eloquent\Collection|\App\FileManagerFile[] $files
* @property-read int|null $files_count
* @property-read \Illuminate\Database\Eloquent\Collection|\App\FileManagerFile[] $files_with_trashed
* @property-read int|null $files_with_trashed_count
* @property-read mixed $used_capacity
* @property-read \Illuminate\Database\Eloquent\Collection|\App\FileManagerFile[] $latest_uploads
* @property-read int|null $latest_uploads_count
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection|\Illuminate\Notifications\DatabaseNotification[] $notifications
* @property-read int|null $notifications_count
* @property-read \Illuminate\Database\Eloquent\Collection|\Laravel\Passport\Token[] $tokens
* @property-read int|null $tokens_count
* @method static \Illuminate\Database\Eloquent\Builder|\App\User newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\App\User newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\App\User query()
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereAvatar($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereEmail($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereEmailVerifiedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\User wherePassword($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereRememberToken($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereUpdatedAt($value)
* @mixin \Eloquent
*/
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
@@ -22,7 +63,7 @@ class User extends Authenticatable
* @var array
*/
protected $fillable = [
'name', 'email', 'password', 'avatar',
'name', 'email', 'password', 'avatar', 'role',
];
/**
@@ -45,9 +86,23 @@ class User extends Authenticatable
];
protected $appends = [
'used_capacity'
'used_capacity', 'storage'
];
/**
* Get user used storage details
*
* @return mixed
*/
public function getStorageAttribute() {
return [
'used' => (float) get_storage_fill_percentage($this->used_capacity, $this->settings->storage_capacity),
'capacity' => $this->settings->storage_capacity,
'capacity_formatted' => Metric::gigabytes($this->settings->storage_capacity)->format(),
];
}
/**
* Get user used storage capacity in bytes
*
@@ -94,7 +149,7 @@ class User extends Authenticatable
*/
public function favourites()
{
return $this->belongsToMany(FileManagerFolder::class, 'favourite_folder', 'user_id', 'folder_unique_id', 'id', 'unique_id')->select(['unique_id', 'name', 'type']);
return $this->belongsToMany(FileManagerFolder::class, 'favourite_folder', 'user_id', 'folder_unique_id', 'id', 'unique_id')->with('shared:token,id,item_id,permission,protected');
}
/**
@@ -104,7 +159,7 @@ class User extends Authenticatable
*/
public function latest_uploads() {
return $this->hasMany(FileManagerFile::class)->orderBy('created_at', 'DESC')->take(7);
return $this->hasMany(FileManagerFile::class)->with(['parent'])->orderBy('created_at', 'DESC')->take(40);
}
/**
@@ -126,4 +181,14 @@ class User extends Authenticatable
return $this->hasMany(FileManagerFile::class)->withTrashed();
}
/**
* Get user attributes
*
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function settings() {
return $this->hasOne(UserSettings::class);
}
}

12
app/UserSettings.php Normal file
View File

@@ -0,0 +1,12 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class UserSettings extends Model
{
public $timestamps = false;
protected $guarded = ['id'];
}

View File

@@ -9,7 +9,7 @@
"license": "MIT",
"require": {
"php": "^7.2",
"askedio/laravel-soft-cascade": "^6.0",
"doctrine/dbal": "^2.10",
"fideloper/proxy": "^4.0",
"fruitcake/laravel-cors": "^1.0",
"gabrielelana/byte-units": "^0.5.0",
@@ -18,9 +18,12 @@
"laravel/passport": "^8.4",
"laravel/scout": "^7.2",
"laravel/tinker": "^2.0",
"league/flysystem-aws-s3-v3": "^1.0",
"league/flysystem-cached-adapter": "^1.0",
"teamtnt/laravel-scout-tntsearch-driver": "^7.2"
},
"require-dev": {
"barryvdh/laravel-ide-helper": "^2.7",
"facade/ignition": "^1.4",
"fzaninotto/faker": "^1.4",
"mockery/mockery": "^1.0",

1897
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -233,6 +233,9 @@ return [
],
'deploy_secret' => env('APP_DEPLOY_SECRET'),
'deploy_branch' => env('APP_DEPLOY_BRANCH'),
'debug_blacklist' => [
'_ENV' => [
'APP_KEY',

View File

@@ -64,6 +64,15 @@ return [
'url' => env('AWS_URL'),
],
'spaces' => [
'driver' => 's3',
'key' => env('DO_SPACES_KEY'),
'secret' => env('DO_SPACES_SECRET'),
'endpoint' => env('DO_SPACES_ENDPOINT'),
'region' => env('DO_SPACES_REGION'),
'bucket' => env('DO_SPACES_BUCKET'),
],
],
];

View File

@@ -2,12 +2,17 @@
return [
'version' => '1.6',
// Your app name
'app_name' => 'VueFileManager',
// Your app logo
'app_logo' => '/assets/images/hero.svg',
// Enable or disable user account registration
'registration' => true,
// Limit your storage size for every user if this option is enabled
'limit_storage_by_capacity' => true,
// Define user storage capacity in MB. E.g. value 2000 is 2.00GB
'user_storage_capacity' => 5000,
];

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class ChangeTypeAttributeInFileManagerFilesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('file_manager_files', function (Blueprint $table) {
DB::statement('ALTER TABLE file_manager_files MODIFY type TEXT;');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('file_manager_files', function (Blueprint $table) {
//
});
}
}

View File

@@ -0,0 +1,38 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateSharesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('shares', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('user_id');
$table->string('token', 16)->unique();
$table->bigInteger('item_id');
$table->enum('type', ['file', 'files', 'folder']);
$table->enum('permission', ['visitor', 'editor'])->nullable();
$table->boolean('protected');
$table->string('password')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('shares');
}
}

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddUserScopeToFileManagerFilesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('file_manager_files', function (Blueprint $table) {
$table->string('user_scope')->after('type')->default('master');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('file_manager_files', function (Blueprint $table) {
//
});
}
}

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddUserScopeToFileManagerFoldersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('file_manager_folders', function (Blueprint $table) {
$table->string('user_scope')->after('type')->default('master');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('file_manager_folders', function (Blueprint $table) {
//
});
}
}

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddRoleToUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->enum('role', ['admin', 'user'])->default('user')->after('id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
//
});
}
}

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUserSettingsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('user_settings', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('user_id');
$table->integer('storage_capacity')->default(5);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('user_attributes');
}
}

View File

@@ -1,272 +0,0 @@
# ************************************************************
# Sequel Pro SQL dump
# Version 4541
#
# http://www.sequelpro.com/
# https://github.com/sequelpro/sequelpro
#
# Host: 127.0.0.1 (MySQL 5.7.25)
# Database: file-manager
# Generation Time: 2020-03-14 17:32:56 +0000
# ************************************************************
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
# Dump of table failed_jobs
# ------------------------------------------------------------
DROP TABLE IF EXISTS `failed_jobs`;
CREATE TABLE `failed_jobs` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`connection` text COLLATE utf8mb4_unicode_ci NOT NULL,
`queue` text COLLATE utf8mb4_unicode_ci NOT NULL,
`payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
`exception` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
`failed_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
# Dump of table favourite_folder
# ------------------------------------------------------------
DROP TABLE IF EXISTS `favourite_folder`;
CREATE TABLE `favourite_folder` (
`user_id` bigint(20) NOT NULL,
`folder_unique_id` bigint(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
# Dump of table file_manager_files
# ------------------------------------------------------------
DROP TABLE IF EXISTS `file_manager_files`;
CREATE TABLE `file_manager_files` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) DEFAULT NULL,
`unique_id` int(11) NOT NULL,
`folder_id` int(11) NOT NULL DEFAULT '0',
`thumbnail` text COLLATE utf8mb4_unicode_ci,
`name` text COLLATE utf8mb4_unicode_ci,
`basename` text COLLATE utf8mb4_unicode_ci,
`mimetype` text COLLATE utf8mb4_unicode_ci,
`filesize` text COLLATE utf8mb4_unicode_ci,
`type` enum('image','file') COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
# Dump of table file_manager_folders
# ------------------------------------------------------------
DROP TABLE IF EXISTS `file_manager_folders`;
CREATE TABLE `file_manager_folders` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) DEFAULT NULL,
`unique_id` int(11) NOT NULL,
`parent_id` int(11) NOT NULL DEFAULT '0',
`name` text COLLATE utf8mb4_unicode_ci,
`type` text COLLATE utf8mb4_unicode_ci,
`deleted_at` timestamp NULL DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
# Dump of table migrations
# ------------------------------------------------------------
DROP TABLE IF EXISTS `migrations`;
CREATE TABLE `migrations` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`migration` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`batch` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
LOCK TABLES `migrations` WRITE;
/*!40000 ALTER TABLE `migrations` DISABLE KEYS */;
INSERT INTO `migrations` (`id`, `migration`, `batch`)
VALUES
(1,'2014_10_12_000000_create_users_table',1),
(2,'2014_10_12_100000_create_password_resets_table',1),
(3,'2016_06_01_000001_create_oauth_auth_codes_table',1),
(4,'2016_06_01_000002_create_oauth_access_tokens_table',1),
(5,'2016_06_01_000003_create_oauth_refresh_tokens_table',1),
(6,'2016_06_01_000004_create_oauth_clients_table',1),
(7,'2016_06_01_000005_create_oauth_personal_access_clients_table',1),
(8,'2019_08_15_171328_create_file_manager_folders',1),
(9,'2019_08_15_171345_create_file_manager_files',1),
(10,'2019_08_19_000000_create_failed_jobs_table',1),
(11,'2020_03_03_065147_add_user_id_to_file_manager_files_table',2),
(12,'2020_03_03_065155_add_user_id_to_file_manager_folders_table',2),
(13,'2020_03_03_070319_create_favourites_folders_table',3);
/*!40000 ALTER TABLE `migrations` ENABLE KEYS */;
UNLOCK TABLES;
# Dump of table oauth_access_tokens
# ------------------------------------------------------------
DROP TABLE IF EXISTS `oauth_access_tokens`;
CREATE TABLE `oauth_access_tokens` (
`id` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`user_id` bigint(20) unsigned DEFAULT NULL,
`client_id` bigint(20) unsigned NOT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`scopes` text COLLATE utf8mb4_unicode_ci,
`revoked` tinyint(1) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`expires_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `oauth_access_tokens_user_id_index` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
# Dump of table oauth_auth_codes
# ------------------------------------------------------------
DROP TABLE IF EXISTS `oauth_auth_codes`;
CREATE TABLE `oauth_auth_codes` (
`id` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`user_id` bigint(20) unsigned NOT NULL,
`client_id` bigint(20) unsigned NOT NULL,
`scopes` text COLLATE utf8mb4_unicode_ci,
`revoked` tinyint(1) NOT NULL,
`expires_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `oauth_auth_codes_user_id_index` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
# Dump of table oauth_clients
# ------------------------------------------------------------
DROP TABLE IF EXISTS `oauth_clients`;
CREATE TABLE `oauth_clients` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) unsigned DEFAULT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`secret` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`redirect` text COLLATE utf8mb4_unicode_ci NOT NULL,
`personal_access_client` tinyint(1) NOT NULL,
`password_client` tinyint(1) NOT NULL,
`revoked` tinyint(1) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `oauth_clients_user_id_index` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
LOCK TABLES `oauth_clients` WRITE;
/*!40000 ALTER TABLE `oauth_clients` DISABLE KEYS */;
INSERT INTO `oauth_clients` (`id`, `user_id`, `name`, `secret`, `redirect`, `personal_access_client`, `password_client`, `revoked`, `created_at`, `updated_at`)
VALUES
(1,1,'vue-filemanager-auth','oULKgESrN8egvBWW0DGNW3aE8yaHWISUODq3ZDRn','/',0,1,0,'2020-03-01 07:49:48','2020-03-01 07:49:48');
/*!40000 ALTER TABLE `oauth_clients` ENABLE KEYS */;
UNLOCK TABLES;
# Dump of table oauth_personal_access_clients
# ------------------------------------------------------------
DROP TABLE IF EXISTS `oauth_personal_access_clients`;
CREATE TABLE `oauth_personal_access_clients` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`client_id` bigint(20) unsigned NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
# Dump of table oauth_refresh_tokens
# ------------------------------------------------------------
DROP TABLE IF EXISTS `oauth_refresh_tokens`;
CREATE TABLE `oauth_refresh_tokens` (
`id` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`access_token_id` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`revoked` tinyint(1) NOT NULL,
`expires_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
# Dump of table password_resets
# ------------------------------------------------------------
DROP TABLE IF EXISTS `password_resets`;
CREATE TABLE `password_resets` (
`email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`token` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
KEY `password_resets_email_index` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
# Dump of table users
# ------------------------------------------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`email_verified_at` timestamp NULL DEFAULT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`avatar` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

1134
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -12,20 +12,22 @@
"devDependencies": {
"axios": "^0.19",
"cross-env": "^5.1",
"laravel-mix": "^5.0.1",
"laravel-mix": "^5.0.4",
"resolve-url-loader": "^2.3.1",
"sass-loader": "^8.0.2",
"vue-template-compiler": "^2.6.11"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.26",
"@fortawesome/free-solid-svg-icons": "^5.12.0",
"@fortawesome/fontawesome-svg-core": "^1.2.28",
"@fortawesome/free-solid-svg-icons": "^5.13.0",
"@fortawesome/vue-fontawesome": "^0.1.9",
"css-element-queries": "^1.2.3",
"lodash": "^4.17.15",
"node-sass": "^4.13.1",
"vee-validate": "^3.2.5",
"node-sass": "^4.14.0",
"vee-validate": "^3.3.0",
"vue": "^2.6.10",
"vuex": "^3.0.1"
"vue-feather-icons": "^5.0.0",
"vue-i18n": "^8.17.4",
"vue-router": "^3.1.6",
"vuex": "^3.3.0"
}
}

View File

@@ -5,6 +5,13 @@
RewriteEngine On
AddType video/ogg .ogv
AddType video/mp4 .mp4
AddType video/webm .webm
<ifModule mod_headers.c>
Header set Connection keep-alive
</ifModule>
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

2
public/css/app.css vendored

File diff suppressed because one or more lines are too long

View File

BIN
public/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

2
public/js/main.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -4,8 +4,14 @@
* Released under the MIT License.
*/
/*!
* vue-i18n v8.17.4
* (c) 2020 kazuya kawaguchi
* Released under the MIT License.
*/
/**
* vee-validate v3.2.5
* vee-validate v3.3.0
* (c) 2020 Abdelrahman Awad
* @license MIT
*/
@@ -20,7 +26,7 @@
*/
/**
* vuex v3.1.3
* vuex v3.3.0
* (c) 2020 Evan You
* @license MIT
*/

View File

@@ -1,4 +1,4 @@
{
"/js/main.js": "/js/main.js?id=cef949b486ef02300d3b",
"/css/app.css": "/css/app.css?id=1864eb943a745d7d07e2"
"/js/main.js": "/js/main.js",
"/css/app.css": "/css/app.css"
}

View File

@@ -1,25 +1,160 @@
<template>
<div id="app">
<VueFileManager style="height: 100%; width: 100%"/>
<div id="vue-file-manager" v-cloak>
<!--System alerts-->
<Alert/>
<div id="application-wrapper" v-if="layout === 'authorized'">
<MobileNavigation />
<!--Share Item setup-->
<ShareCreate/>
<ShareEdit/>
<!--Move item setup-->
<MoveItem/>
<!--Mobile Menu-->
<MobileMenu/>
<!--Navigation Sidebar-->
<MenuBar/>
<!--Toastr-->
<ToastrWrapper/>
<!--File page-->
<keep-alive :include="['Admin', 'Users']">
<router-view :class="{'is-scaled-down': isScaledDown}"/>
</keep-alive>
</div>
<router-view v-if="layout === 'unauthorized'"/>
<!--Background vignette-->
<Vignette/>
</div>
</template>
<script>
import VueFileManager from './components/VueFileManager.vue'
import ToastrWrapper from '@/components/Others/Notifications/ToastrWrapper'
import MobileNavigation from '@/components/Others/MobileNavigation'
import MobileMenu from '@/components/FilesView/MobileMenu'
import ShareCreate from '@/components/Others/ShareCreate'
import ShareEdit from '@/components/Others/ShareEdit'
import MoveItem from '@/components/Others/MoveItem'
import Vignette from '@/components/Others/Vignette'
import MenuBar from '@/components/Sidebar/MenuBar'
import Alert from '@/components/FilesView/Alert'
import {includes} from 'lodash'
import {mapGetters} from 'vuex'
import {events} from "./bus"
export default {
name: 'app',
components: {
VueFileManager
MobileNavigation,
ToastrWrapper,
ShareCreate,
MobileMenu,
ShareEdit,
MoveItem,
Vignette,
MenuBar,
Alert,
},
computed: {
...mapGetters([
'isLogged', 'isGuest'
]),
layout() {
if (includes(['VerifyByPassword', 'SharedPage', 'NotFoundShared', 'SignIn', 'SignUp', 'ForgottenPassword', 'CreateNewPassword'], this.$route.name)) {
return 'unauthorized'
}
return 'authorized'
}
},
data() {
return {
isScaledDown: false,
}
},
beforeMount() {
// Store config to vuex
this.$store.commit('INIT', {
authCookie: this.$root.$data.config.hasAuthCookie,
config: this.$root.$data.config,
rootDirectory: {
name: this.$t('locations.home'),
location: 'base',
unique_id: 0,
}
})
},
mounted() {
// Handle mobile navigation scale animation
events.$on('show:mobile-navigation', () => this.isScaledDown = true)
events.$on('hide:mobile-navigation', () => this.isScaledDown = false)
events.$on('mobileMenu:show', () => this.isScaledDown = true)
events.$on('fileItem:deselect', () => this.isScaledDown = false)
}
}
</script>
<style lang="scss">
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@200;300;400;600;700;900&display=swap');
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
#app {
height: 100%;
[v-cloak],
[v-cloak] > * {
display: none
}
* {
outline: 0;
margin: 0;
padding: 0;
font-family: 'Nunito', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
box-sizing: border-box;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
font-size: 16px;
}
#auth {
width: 100%;
height: 100%;
}
#vue-file-manager {
position: absolute;
width: 100%;
height: 100%;
overflow-y: auto;
}
@media only screen and (max-width: 690px) {
.is-scaled-down {
@include transform(scale(0.95));
}
}
// Dark mode support
@media (prefers-color-scheme: dark) {
body, html {
background: $dark_mode_background;
color: $dark_mode_text_primary;
img {
opacity: .95;
}
}
}
</style>

View File

@@ -28,7 +28,8 @@
</script>
<style scoped lang="scss">
@import "@assets/app.scss";
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.button {
cursor: pointer;

View File

@@ -19,8 +19,3 @@
}
}
</script>
<style scoped lang="scss">
</style>

View File

@@ -5,21 +5,16 @@
</template>
<script>
export default {
name: 'AuthContentWrapper',
}
</script>
<style scoped lang="scss">
@import "@assets/app.scss";
#auth {
height: 100%;
width: 100%;
display: table;
//display: flex;
//align-items: center;
//justify-content: center;
}
</style>

View File

@@ -1,32 +1,29 @@
<template>
<transition name="vignette">
<div class="popup" v-show="isVisibleWrapper">
<transition name="popup">
<div v-show="isVisiblePopup" class="popup-wrapper">
<div class="popup-image">
<span class="emoji">{{ emoji }}</span>
</div>
<div class="popup-content">
<h1 v-if="title" class="title">{{ title }}</h1>
<p v-if="message" class="message">{{ message }}</p>
</div>
<div class="popup-actions">
<ButtonBase
@click.native="closePopup"
:button-style="buttonStyle"
class="action-confirm"
>{{ button }}
</ButtonBase>
</div>
<transition name="popup">
<div @click.self="closePopup" class="popup" v-if="isVisibleWrapper">
<div class="popup-wrapper">
<div class="popup-image">
<span class="emoji">{{ emoji }}</span>
</div>
</transition>
<div class="popup-vignette" @click="closePopup"></div>
<div class="popup-content">
<h1 v-if="title" class="title">{{ title }}</h1>
<p v-if="message" class="message">{{ message }}</p>
</div>
<div class="popup-actions">
<ButtonBase
@click.native="closePopup"
:button-style="buttonStyle"
class="action-confirm"
>{{ button }}
</ButtonBase>
</div>
</div>
</div>
</transition>
</template>
<script>
import ButtonBase from '@/components/VueFileManagerComponents/FilesView/ButtonBase'
import ButtonBase from '@/components/FilesView/ButtonBase'
import {events} from '@/bus'
export default {
@@ -38,7 +35,6 @@
return {
isVisibleWrapper: false,
buttonStyle: undefined,
isVisiblePopup: false,
message: undefined,
title: undefined,
button: undefined,
@@ -47,26 +43,20 @@
},
methods: {
closePopup() {
// Emit event
events.$emit('alert:close')
// Hide popup wrapper
this.isVisibleWrapper = false
this.isVisiblePopup = false
events.$emit('popup:close')
}
},
mounted() {
// Show alert
events.$on('alert:open', args => {
this.isVisibleWrapper = true
this.isVisiblePopup = true
this.title = args.title
this.message = args.message
this.button = 'Thats horrible!'
this.button = this.$t('alerts.error_confirm')
this.emoji = '😢😢😢'
this.buttonStyle = 'danger'
this.buttonStyle = 'danger-solid'
if (args.emoji) {
this.emoji = args.emoji
@@ -76,12 +66,11 @@
// Show alert
events.$on('success:open', args => {
this.isVisibleWrapper = true
this.isVisiblePopup = true
this.title = args.title
this.message = args.message
this.button = 'Awesome!'
this.button = this.$t('alerts.success_confirm')
this.emoji = '🥳🥳🥳'
this.buttonStyle = 'theme'
@@ -92,7 +81,6 @@
// Close popup
events.$on('popup:close', () => {
this.isVisiblePopup = false
this.isVisibleWrapper = false
})
}
@@ -100,7 +88,8 @@
</script>
<style scoped lang="scss">
@import "@assets/app.scss";
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.popup {
position: absolute;
@@ -110,15 +99,7 @@
bottom: 0;
z-index: 20;
overflow: auto;
.popup-vignette {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.25);
}
height: 100%;
}
.popup-wrapper {
@@ -130,8 +111,8 @@
top: 50%;
transform: translateY(-50%) scale(1);
margin: 0 auto;
padding: 40px;
box-shadow: 0 7px 250px rgba(25, 54, 60, 0.2);
padding: 20px;
box-shadow: $light_mode_popup_shadow;
border-radius: 8px;
text-align: center;
background: white;
@@ -156,7 +137,7 @@
.message {
@include font-size(16);
color: #8b8f9a;
color: #333;
margin-top: 5px;
}
}
@@ -180,12 +161,8 @@
@media (prefers-color-scheme: dark) {
.popup .popup-vignette {
background: $dark_mode_vignette;
}
.popup-wrapper {
background: $dark_mode_foreground;
background: $dark_mode_background;
}
.popup-content {
@@ -211,28 +188,11 @@
@keyframes popup-in {
0% {
opacity: 0;
transform: translateY(-50%) scale(0.7);
}
100% {
opacity: 1;
transform: translateY(-50%) scale(1);
}
}
.vignette-enter-active {
animation: vignette-in 0.15s ease;
}
.vignette-leave-active {
animation: vignette-in 0.15s 0.15s ease reverse;
}
@keyframes vignette-in {
0% {
opacity: 0;
transform: scale(0.7);
}
100% {
opacity: 1;
transform: scale(1);
}
}
</style>

View File

@@ -1,28 +1,33 @@
<template>
<button class="button-base" :class="buttonStyle" type="button">
<slot></slot>
<span v-if="loading" class="icon">
<FontAwesomeIcon icon="sync-alt" class="sync-alt"/>
</span>
<slot v-if="! loading"></slot>
</button>
</template>
<script>
export default {
name: 'ButtonBase',
props: ['buttonStyle']
props: ['buttonStyle', 'loading']
}
</script>
<style scoped lang="scss">
@import "@assets/app.scss";
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.button-base {
@include font-size(16);
font-weight: 600;
@include font-size(15);
font-weight: 700;
cursor: pointer;
transition: 0.15s all ease;
border-radius: 8px;
border: 0;
padding: 10px 28px;
display: inline-block;
white-space: nowrap;
&:active {
transform: scale(0.95);
@@ -38,12 +43,30 @@
background: rgba($danger, .1);
}
&.danger-solid {
color: white;
background: $danger;
}
&.secondary {
color: $text;
background: $light_background;
}
}
.sync-alt {
animation: spin 1s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
@media (prefers-color-scheme: dark) {
.button-base {

View File

@@ -31,11 +31,12 @@
</script>
<style scoped lang="scss">
@import "@assets/app.scss";
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.button-base {
@include font-size(16);
font-weight: 600;
@include font-size(15);
font-weight: 700;
cursor: pointer;
transition: 0.15s all ease;
border-radius: 8px;

View File

@@ -0,0 +1,515 @@
<template>
<div
:style="{ top: positionY + 'px', left: positionX + 'px' }"
@click="closeAndResetContextMenu"
class="contextmenu"
v-show="isVisible"
ref="contextmenu"
>
<!--ContextMenu for trash location-->
<div v-if="$isThisLocation(['trash', 'trash-root']) && $checkPermission('master')" id="menu-list" class="menu-options">
<ul class="menu-option-group">
<li class="menu-option" @click="$store.dispatch('restoreItem', item)" v-if="item">
<div class="icon">
<life-buoy-icon size="17"></life-buoy-icon>
</div>
<div class="text-label">
{{ $t('context_menu.restore') }}
</div>
</li>
<li class="menu-option" @click="deleteItem" v-if="item">
<div class="icon">
<trash-2-icon size="17"></trash-2-icon>
</div>
<div class="text-label">
{{ $t('context_menu.delete') }}
</div>
</li>
<li class="menu-option" @click="$store.dispatch('emptyTrash')">
<div class="icon">
<trash-icon size="17"></trash-icon>
</div>
<div class="text-label">
{{ $t('context_menu.empty_trash') }}
</div>
</li>
</ul>
<ul class="menu-option-group" v-if="item">
<li class="menu-option" @click="ItemDetail">
<div class="icon">
<eye-icon size="17"></eye-icon>
</div>
<div class="text-label">
{{ $t('context_menu.detail') }}
</div>
</li>
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
<div class="icon">
<download-cloud-icon size="17"></download-cloud-icon>
</div>
<div class="text-label">
{{ $t('context_menu.download') }}
</div>
</li>
</ul>
</div>
<!--ContextMenu for Base location with MASTER permission-->
<div v-if="$isThisLocation(['shared']) && $checkPermission('master')" id="menu-list" class="menu-options">
<ul class="menu-option-group" v-if="item && isFolder">
<li class="menu-option" @click="addToFavourites">
<div class="icon">
<star-icon size="17"></star-icon>
</div>
<div class="text-label">
{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}
</div>
</li>
</ul>
<ul class="menu-option-group" v-if="item">
<li class="menu-option" @click="shareItem">
<div class="icon">
<link-icon size="17"></link-icon>
</div>
<div class="text-label">
{{ item.shared ? $t('context_menu.share_edit') : $t('context_menu.share') }}
</div>
</li>
<li class="menu-option" @click="deleteItem">
<div class="icon">
<trash-2-icon size="17"></trash-2-icon>
</div>
<div class="text-label">
{{ $t('context_menu.delete') }}
</div>
</li>
</ul>
<ul class="menu-option-group" v-if="item">
<li class="menu-option" @click="ItemDetail" v-if="item">
<div class="icon">
<eye-icon size="17"></eye-icon>
</div>
<div class="text-label">
{{ $t('context_menu.detail') }}
</div>
</li>
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
<div class="icon">
<download-cloud-icon size="17"></download-cloud-icon>
</div>
<div class="text-label">
{{ $t('context_menu.download') }}
</div>
</li>
</ul>
</div>
<!--ContextMenu for Base location with MASTER permission-->
<div v-if="$isThisLocation(['base', 'participant_uploads', 'latest']) && $checkPermission('master')" id="menu-list" class="menu-options">
<ul class="menu-option-group" v-if="! $isThisLocation(['participant_uploads', 'latest'])">
<li class="menu-option" @click="addToFavourites" v-if="item && isFolder">
<div class="icon">
<star-icon size="17"></star-icon>
</div>
<div class="text-label">
{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}
</div>
</li>
<li class="menu-option" @click="createFolder">
<div class="icon">
<folder-plus-icon size="17"></folder-plus-icon>
</div>
<div class="text-label">
{{ $t('context_menu.create_folder') }}
</div>
</li>
</ul>
<ul class="menu-option-group" v-if="item">
<li class="menu-option" @click="moveItem">
<div class="icon">
<corner-down-right-icon size="17"></corner-down-right-icon>
</div>
<div class="text-label">
{{ $t('context_menu.move') }}
</div>
</li>
<li class="menu-option" @click="shareItem">
<div class="icon">
<link-icon size="17"></link-icon>
</div>
<div class="text-label">
{{ item.shared ? $t('context_menu.share_edit') : $t('context_menu.share') }}
</div>
</li>
<li class="menu-option" @click="deleteItem">
<div class="icon">
<trash-2-icon size="17"></trash-2-icon>
</div>
<div class="text-label">
{{ $t('context_menu.delete') }}
</div>
</li>
</ul>
<ul class="menu-option-group" v-if="item">
<li class="menu-option" @click="ItemDetail">
<div class="icon">
<eye-icon size="17"></eye-icon>
</div>
<div class="text-label">
{{ $t('context_menu.detail') }}
</div>
</li>
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
<div class="icon">
<download-cloud-icon size="17"></download-cloud-icon>
</div>
<div class="text-label">
{{ $t('context_menu.download') }}
</div>
</li>
</ul>
</div>
<!--ContextMenu for Base location with EDITOR permission-->
<div v-if="$isThisLocation(['base', 'public']) && $checkPermission('editor')" id="menu-list" class="menu-options">
<ul class="menu-option-group">
<li class="menu-option" @click="createFolder">
<div class="icon">
<folder-plus-icon size="17"></folder-plus-icon>
</div>
<div class="text-label">
{{ $t('context_menu.create_folder') }}
</div>
</li>
</ul>
<ul class="menu-option-group" v-if="item">
<li class="menu-option" @click="moveItem">
<div class="icon">
<corner-down-right-icon size="17"></corner-down-right-icon>
</div>
<div class="text-label">
{{ $t('context_menu.move') }}
</div>
</li>
<li class="menu-option" @click="deleteItem">
<div class="icon">
<trash-2-icon size="17"></trash-2-icon>
</div>
<div class="text-label">
{{ $t('context_menu.delete') }}
</div>
</li>
</ul>
<ul class="menu-option-group" v-if="item">
<li class="menu-option" @click="ItemDetail">
<div class="icon">
<eye-icon size="17"></eye-icon>
</div>
<div class="text-label">
{{ $t('context_menu.detail') }}
</div>
</li>
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
<div class="icon">
<download-cloud-icon size="17"></download-cloud-icon>
</div>
<div class="text-label">
{{ $t('context_menu.download') }}
</div>
</li>
</ul>
</div>
<!--ContextMenu for Base location with VISITOR permission-->
<div v-if="$isThisLocation(['base', 'public']) && $checkPermission('visitor')" id="menu-list" class="menu-options">
<ul class="menu-option-group" v-if="item">
<li class="menu-option" @click="ItemDetail">
<div class="icon">
<eye-icon size="17"></eye-icon>
</div>
<div class="text-label">
{{ $t('context_menu.detail') }}
</div>
</li>
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
<div class="icon">
<download-cloud-icon size="17"></download-cloud-icon>
</div>
<div class="text-label">
{{ $t('context_menu.download') }}
</div>
</li>
</ul>
</div>
</div>
</template>
<script>
import {
CornerDownRightIcon,
DownloadCloudIcon,
FolderPlusIcon,
LifeBuoyIcon,
Trash2Icon,
TrashIcon,
StarIcon,
LinkIcon,
EyeIcon,
} from 'vue-feather-icons'
import {mapGetters} from 'vuex'
import {events} from '@/bus'
export default {
name: 'ContextMenu',
components: {
CornerDownRightIcon,
DownloadCloudIcon,
FolderPlusIcon,
LifeBuoyIcon,
Trash2Icon,
TrashIcon,
LinkIcon,
StarIcon,
EyeIcon,
},
computed: {
...mapGetters(['app']),
isFolder() {
return this.item && this.item.type === 'folder'
},
isFile() {
return (this.item && this.item.type !== 'folder') && (this.item && this.item.type !== 'image')
},
isImage() {
return this.item && this.item.type === 'image'
},
isInFavourites() {
return this.app.favourites.find(el => el.unique_id == this.item.unique_id)
},
},
data() {
return {
item: undefined,
isVisible: false,
positionX: 0,
positionY: 0
}
},
methods: {
moveItem() {
// Open move item popup
events.$emit('popup:open', {name: 'move', item: this.item})
},
shareItem() {
if (this.item.shared) {
// Open share item popup
events.$emit('popup:open', {name: 'share-edit', item: this.item})
} else {
// Open share item popup
events.$emit('popup:open', {name: 'share-create', item: this.item})
}
},
addToFavourites() {
// Check if folder is in favourites and then add/remove from favourites
if (this.app.favourites && !this.app.favourites.find(el => el.unique_id == this.item.unique_id)) {
this.$store.dispatch('addToFavourites', this.item)
} else {
this.$store.dispatch('removeFromFavourites', this.item)
}
},
downloadItem() {
// Download file
this.$downloadFile(
this.item.file_url,
this.item.name + '.' + this.item.mimetype
)
},
ItemDetail() {
// Dispatch load file info detail
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
// Show panel if is not open
this.$store.dispatch('fileInfoToggle', true)
},
deleteItem() {
// Dispatch remove item
this.$store.dispatch('deleteItem', this.item)
},
createFolder() {
// Create folder
this.$createFolder(this.$t('popup_create_folder.folder_default_name'))
},
closeAndResetContextMenu() {
// Close context menu
this.isVisible = false
// Reset item container
this.item = undefined
},
showFolderActionsMenu() {
let container = document.getElementById('folder-actions')
this.positionX = container.offsetLeft + 16
this.positionY = container.offsetTop + 30
// Show context menu
this.isVisible = true
},
showContextMenu(event) {
let parent = document.getElementById('menu-list')
let nodesSameClass = parent.getElementsByClassName("menu-option")
let VerticalOffsetArea = nodesSameClass.length * 50
let HorizontalOffsetArea = 190
let container = document.getElementById('files-view')
var offset = container.getClientRects()[0];
let x = event.clientX - offset.left
let y = event.clientY - offset.top
// Set position Y
if ((container.offsetHeight - y) < VerticalOffsetArea) {
this.positionY = y - VerticalOffsetArea
} else {
this.positionY = y
}
// Set position X
if ((container.offsetWidth - x) < HorizontalOffsetArea) {
this.positionX = x - HorizontalOffsetArea
} else {
this.positionX = x
}
// Show context menu
this.isVisible = true
}
},
created() {
events.$on('contextMenu:show', (event, item) => {
// Store item
this.item = item
// Show context menu
setTimeout(() => this.showContextMenu(event, item), 10)
})
events.$on('contextMenu:hide', () => (this.closeAndResetContextMenu()))
events.$on('folder:actions', folder => {
// Store item
this.item = folder
if (this.isVisible)
this.isVisible = false
else
this.showFolderActionsMenu()
})
}
}
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.menu-option {
display: flex;
align-items: center;
.icon {
margin-right: 20px;
line-height: 0;
}
.text-label {
@include font-size(16);
}
}
.contextmenu {
min-width: 250px;
position: absolute;
z-index: 99;
box-shadow: $shadow;
background: white;
border-radius: 8px;
overflow: hidden;
&.showed {
display: block;
}
}
.menu-options {
list-style: none;
width: 100%;
margin: 0;
padding: 0;
.menu-option-group {
padding: 5px 0;
border-bottom: 1px solid $light_mode_border;
&:first-child {
padding-top: 0;
}
&:last-child {
padding-bottom: 0;
border-bottom: none;
}
}
.menu-option {
white-space: nowrap;
font-weight: 700;
@include font-size(14);
padding: 15px 20px;
cursor: pointer;
width: 100%;
color: $text;
&:hover {
background: $light_background;
.text-label {
color: $theme;
}
path, line, polyline, rect, circle, polygon {
stroke: $theme;
}
}
}
}
@media (prefers-color-scheme: dark) {
.contextmenu {
background: $dark_mode_foreground;
.menu-options {
.menu-option-group {
border-color: $dark_mode_border_color;
}
.menu-option {
color: $dark_mode_text_primary;
&:hover {
background: rgba($theme, 0.1);
}
}
}
}
}
</style>

View File

@@ -0,0 +1,354 @@
<template>
<div id="desktop-toolbar">
<div class="toolbar-wrapper">
<!-- Go back-->
<div class="toolbar-go-back" v-if="homeDirectory">
<div @click="goBack" class="go-back-button">
<chevron-left-icon size="17" :class="{'is-active': browseHistory.length > 1}" class="icon-back"></chevron-left-icon>
<span class="back-directory-title">
{{ directoryName }}
</span>
<span @click.stop="folderActions" v-if="browseHistory.length > 1 && $isThisLocation(['base', 'public'])" class="folder-options" id="folder-actions">
<more-horizontal-icon size="14" class="icon-more"></more-horizontal-icon>
</span>
</div>
</div>
<!-- Tools-->
<div class="toolbar-tools">
<!--Search bar-->
<div class="toolbar-button-wrapper">
<SearchBar/>
</div>
<!--Files controlls-->
<div class="toolbar-button-wrapper" v-if="$checkPermission(['master', 'editor'])">
<ToolbarButtonUpload
:class="{'is-inactive': canUploadInView}"
:action="$t('actions.upload')"
/>
<ToolbarButton
:class="{'is-inactive': canCreateFolderInView}"
@click.native="createFolder"
source="folder-plus"
:action="$t('actions.create_folder')"
/>
</div>
<div class="toolbar-button-wrapper"
v-if="$checkPermission(['master', 'editor'])">
<ToolbarButton
source="move"
:class="{'is-inactive': canMoveInView}"
:action="$t('actions.move')"
@click.native="moveItem"
/>
<ToolbarButton
v-if="! $isThisLocation(['public'])"
source="share"
:class="{'is-inactive': canShareInView}"
:action="$t('actions.share')"
@click.native="shareItem"
/>
<ToolbarButton
source="trash"
:class="{'is-inactive': canDeleteInView}"
:action="$t('actions.delete')"
@click.native="deleteItem"
/>
</div>
<!--View options-->
<div class="toolbar-button-wrapper">
<ToolbarButton
:source="preview"
:action="$t('actions.preview')"
@click.native="$store.dispatch('changePreviewType')"
/>
<ToolbarButton
:class="{ active: fileInfoVisible }"
@click.native="$store.dispatch('fileInfoToggle')"
source="info"
/>
</div>
</div>
</div>
<UploadProgress />
</div>
</template>
<script>
import ToolbarButtonUpload from '@/components/FilesView/ToolbarButtonUpload'
import { ChevronLeftIcon, MoreHorizontalIcon } from 'vue-feather-icons'
import UploadProgress from '@/components/FilesView/UploadProgress'
import ToolbarButton from '@/components/FilesView/ToolbarButton'
import SearchBar from '@/components/FilesView/SearchBar'
import {mapGetters} from 'vuex'
import {events} from '@/bus'
import {last} from 'lodash'
export default {
name: 'ToolBar',
components: {
ToolbarButtonUpload,
MoreHorizontalIcon,
ChevronLeftIcon,
UploadProgress,
ToolbarButton,
SearchBar
},
computed: {
...mapGetters([
'FilePreviewType',
'fileInfoVisible',
'fileInfoDetail',
'currentFolder',
'browseHistory',
'homeDirectory',
]),
directoryName() {
return this.currentFolder ? this.currentFolder.name : this.homeDirectory.name
},
preview() {
return this.FilePreviewType === 'list' ? 'th' : 'th-list'
},
canCreateFolderInView() {
return ! this.$isThisLocation(['base', 'public'])
},
canDeleteInView() {
return ! this.$isThisLocation(['trash', 'trash-root', 'base', 'participant_uploads', 'latest', 'shared', 'public'])
},
canUploadInView() {
return ! this.$isThisLocation(['base', 'public'])
},
canMoveInView() {
return ! this.$isThisLocation(['base', 'participant_uploads', 'latest', 'shared', 'public'])
},
canShareInView() {
return ! this.$isThisLocation(['base', 'participant_uploads', 'latest', 'shared', 'public'])
}
},
methods: {
goBack() {
// Get previous folder
let previousFolder = last(this.browseHistory)
if (! previousFolder)
return
if (previousFolder.location === 'trash-root') {
this.$store.dispatch('getTrash')
} else if (previousFolder.location === 'shared') {
this.$store.dispatch('getShared')
} else {
if ( this.$isThisLocation('public') ) {
this.$store.dispatch('browseShared', [{folder: previousFolder, back: true, init: false}])
} else {
this.$store.dispatch('getFolder', [{folder: previousFolder, back: true, init: false}])
}
}
},
folderActions() {
events.$emit('folder:actions', this.currentFolder)
},
deleteItem() {
events.$emit('items:delete')
},
createFolder() {
this.$createFolder()
},
moveItem() {
events.$emit('popup:open', {name: 'move', item: this.fileInfoDetail})
},
shareItem() {
if (this.fileInfoDetail.shared) {
events.$emit('popup:open', {name: 'share-edit', item: this.fileInfoDetail})
} else {
events.$emit('popup:open', {name: 'share-create', item: this.fileInfoDetail})
}
}
},
}
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.toolbar-wrapper {
padding-top: 10px;
padding-bottom: 10px;
display: flex;
position: relative;
z-index: 2;
> div {
flex-grow: 1;
align-self: center;
white-space: nowrap;
}
}
.directory-name {
vertical-align: middle;
@include font-size(17);
color: $text;
font-weight: 700;
max-width: 220px;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
}
.icon-back {
vertical-align: middle;
cursor: pointer;
margin-right: 6px;
opacity: 0.15;
pointer-events: none;
@include transition(150ms);
&.is-active {
opacity: 1;
pointer-events: initial;
}
}
.toolbar-go-back {
cursor: pointer;
.folder-options {
vertical-align: middle;
margin-left: 6px;
padding: 1px 4px;
line-height: 0;
border-radius: 3px;
@include transition(150ms);
svg circle {
@include transition(150ms);
}
&:hover {
background: $light_background;
svg circle {
stroke: $theme;
}
}
.icon-more {
vertical-align: middle;
}
}
.back-directory-title {
@include font-size(15);
line-height: 1;
font-weight: 700;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: middle;
color: $text;
}
}
.toolbar-position {
text-align: center;
span {
@include font-size(17);
font-weight: 600;
}
}
.toolbar-tools {
text-align: right;
.toolbar-button-wrapper {
margin-left: 28px;
display: inline-block;
vertical-align: middle;
&:first-child {
margin-left: 0 !important;
}
}
.button {
margin-left: 5px;
&.active {
/deep/ svg {
line, circle {
stroke: $theme;
}
}
}
&.is-inactive {
opacity: 0.25;
pointer-events: none;
}
&:first-child {
margin-left: 0;
}
}
}
@media only screen and (max-width: 1024px) {
.toolbar-go-back .back-directory-title {
max-width: 120px;
}
.toolbar-tools {
.button {
margin-left: 0;
height: 40px;
width: 40px;
}
.toolbar-button-wrapper {
margin-left: 25px;
}
}
}
@media only screen and (max-width: 960px) {
#desktop-toolbar {
display: none;
}
}
@media (prefers-color-scheme: dark) {
.toolbar .directory-name {
color: $dark_mode_text_primary;
}
.toolbar-go-back {
.back-directory-title {
color: $dark_mode_text_primary;
}
.folder-options {
&:hover {
background: $dark_mode_foreground;
}
}
}
}
</style>

View File

@@ -0,0 +1,67 @@
<template>
<div class="empty-message">
<div class="message">
<eye-off-icon v-if="icon === 'eye-off'" size="36" class="icon"></eye-off-icon>
<p>{{ message }}</p>
</div>
</div>
</template>
<script>
import { EyeOffIcon } from 'vue-feather-icons'
export default {
name: 'EmptyMessage',
props: ['icon', 'message'],
components: {
EyeOffIcon
}
}
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.empty-message {
text-align: center;
display: flex;
align-items: center;
height: 100%;
.message {
margin: 0 auto;
p {
margin-top: 10px;
max-width: 130px;
@include font-size(13);
font-weight: 500;
color: $text-muted;
}
.icon {
path, line, polyline, rect, circle {
stroke: $text;
}
}
}
}
@media (prefers-color-scheme: dark) {
.empty-message {
.message {
.icon {
path, line, polyline, rect, circle {
stroke: $dark_mode_text_secondary;
}
}
p {
color: $dark_mode_text_secondary;
}
}
}
}
</style>

View File

@@ -1,20 +1,35 @@
<template>
<div class="empty-page" v-if="isLoading || isEmpty">
<div class="empty-state">
<div class="text-content" v-if="isEmpty && !isLoading">
<h1 class="title">There is Nothing</h1>
<p v-if="! isTrash" class="description">
Upload some files here easily via upload button
</p>
<ButtonUpload
v-if="! isTrash"
@input.native="$uploadFiles(files)"
v-model="files"
button-style="theme"
>Upload File
</ButtonUpload
>
<!--Shared empty message-->
<div class="text-content" v-if="$isThisLocation(['shared']) && ! isLoading">
<h1 class="title">{{ $t('shared.empty_shared') }}</h1>
</div>
<!--Trash empty message-->
<div class="text-content" v-if="$isThisLocation(['trash', 'trash-root']) && ! isLoading">
<h1 class="title">{{ $t('empty_page.title') }}</h1>
</div>
<!--Trash empty message-->
<div class="text-content" v-if="$isThisLocation(['participant_uploads']) && ! isLoading">
<h1 class="title">{{ $t('messages.nothing_from_participants') }}</h1>
</div>
<!--Base file browser empty message-->
<div class="text-content" v-if="$isThisLocation(['base', 'public', 'latest']) && !isLoading">
<h1 class="title">{{ $t('empty_page.title') }}</h1>
<p v-if="$checkPermission(['master', 'editor'])" class="description">{{ $t('empty_page.description') }}</p>
<ButtonUpload
v-if="$checkPermission(['master', 'editor'])"
button-style="theme"
>
{{ $t('empty_page.call_to_action') }}
</ButtonUpload>
</div>
<!--Spinner-->
<div class="text-content" v-if="isLoading">
<Spinner/>
</div>
@@ -23,8 +38,8 @@
</template>
<script>
import ButtonUpload from '@/components/VueFileManagerComponents/FilesView/ButtonUpload'
import Spinner from '@/components/VueFileManagerComponents/FilesView/Spinner'
import ButtonUpload from '@/components/FilesView/ButtonUpload'
import Spinner from '@/components/FilesView/Spinner'
import {mapGetters} from 'vuex'
export default {
@@ -37,22 +52,15 @@
computed: {
...mapGetters(['data', 'isLoading', 'currentFolder']),
isEmpty() {
return this.data.length == 0
},
isTrash() {
return typeof this.currentFolder.unique_id === 'undefined'
}
},
data() {
return {
files: undefined
return this.data && this.data.length == 0
}
}
}
</script>
<style scoped lang="scss">
@import "@assets/app.scss";
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.empty-page {
position: absolute;
@@ -76,14 +84,14 @@
margin: 30px 0;
.title {
@include font-size(24);
@include font-size(20);
color: $text;
font-weight: 600;
font-weight: 700;
margin: 0;
}
.description {
@include font-size(15);
@include font-size(13);
color: $text-muted;
margin-bottom: 20px;
display: block;

Some files were not shown because too many files have changed in this diff Show More