Compare commits
284 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a90311593b | ||
|
|
db57bde4fc | ||
|
|
92e02d8b57 | ||
|
|
b42d480c91 | ||
|
|
c8a9f18265 | ||
|
|
56b7f30d47 | ||
|
|
b8790a964b | ||
|
|
05f850ab2c | ||
|
|
c2868c051d | ||
|
|
28b39a79e6 | ||
|
|
2dbd9dd62d | ||
|
|
9dbce7a73a | ||
|
|
8ac5c8fd38 | ||
|
|
2a105877f3 | ||
|
|
28efba5773 | ||
|
|
60f02622da | ||
|
|
7eee7deba5 | ||
|
|
ba0b2bd3b9 | ||
|
|
86090b5870 | ||
|
|
39681bc48a | ||
|
|
96e1bdd99f | ||
|
|
eebeee6948 | ||
|
|
7be02edead | ||
|
|
d65c27091c | ||
|
|
6c3630085e | ||
|
|
f6dbb5e71e | ||
|
|
a80e4364ae | ||
|
|
bfb3888555 | ||
|
|
5e408267ee | ||
|
|
a4725df5f7 | ||
|
|
dee562c56e | ||
|
|
e1016502a1 | ||
|
|
541924448b | ||
|
|
18b97866f2 | ||
|
|
6f2278b908 | ||
|
|
bdd8d63162 | ||
|
|
8ca7881c5e | ||
|
|
8d04a94dbc | ||
|
|
d92bb50a03 | ||
|
|
44158c74e3 | ||
|
|
847bcec22f | ||
|
|
e984ae6beb | ||
|
|
e2a52d27f5 | ||
|
|
9c92cffde3 | ||
|
|
ce20452f38 | ||
|
|
6c888c6bd3 | ||
|
|
2b2d9a0764 | ||
|
|
ed2d008f4b | ||
|
|
9972f471c4 | ||
|
|
03ef16d90d | ||
|
|
4158d4f31e | ||
|
|
e65acd8a4f | ||
|
|
ba5e05f77a | ||
|
|
82cf82e4b5 | ||
|
|
f5e19e47f7 | ||
|
|
43b1aa7f89 | ||
|
|
0e1ebdd809 | ||
|
|
6e3adcd459 | ||
|
|
9c147165e1 | ||
|
|
689b064756 | ||
|
|
6b32ae9795 | ||
|
|
267556b39d | ||
|
|
eb2e39cd32 | ||
|
|
58ae75ecc9 | ||
|
|
a5dd0e0d30 | ||
|
|
cec2450940 | ||
|
|
fdd8f16384 | ||
|
|
2112fe879b | ||
|
|
078d920c19 | ||
|
|
98d1926ab3 | ||
|
|
2263cc9511 | ||
|
|
9a736a2615 | ||
|
|
4b1e5fcb46 | ||
|
|
a0c39bd955 | ||
|
|
973b301a46 | ||
|
|
e0f192777f | ||
|
|
ce1bad57cd | ||
|
|
77b126b85a | ||
|
|
3adf57a6b1 | ||
|
|
cc72e4e3a2 | ||
|
|
3285af3603 | ||
|
|
04990fcf7b | ||
|
|
ba28ac6184 | ||
|
|
a100671cc0 | ||
|
|
ded02fc15b | ||
|
|
64fd6a2265 | ||
|
|
c2a5d4bc74 | ||
|
|
fed95cbd64 | ||
|
|
e60bbb369a | ||
|
|
7379d17a40 | ||
|
|
26e0535407 | ||
|
|
0f8a89bbad | ||
|
|
2f89f6303a | ||
|
|
4b3ca7e34b | ||
|
|
2c0cf43802 | ||
|
|
d255b01c70 | ||
|
|
6a9edc49c0 | ||
|
|
96faf2de0e | ||
|
|
5a2e6a5e53 | ||
|
|
c509eeceb1 | ||
|
|
299292a817 | ||
|
|
b11bd0e521 | ||
|
|
8fb859b441 | ||
|
|
28a5f58b80 | ||
|
|
7da4d1f64b | ||
|
|
07086c7550 | ||
|
|
5246c47c86 | ||
|
|
2975d1555d | ||
|
|
bd946be0b0 | ||
|
|
e6ff90f6fc | ||
|
|
08dc813af9 | ||
|
|
9098634b99 | ||
|
|
00213824f1 | ||
|
|
65624326c7 | ||
|
|
e92d9344b9 | ||
|
|
55cf58fffd | ||
|
|
a3c43af7ba | ||
|
|
a10d394abb | ||
|
|
b16f22b0eb | ||
|
|
5bc66d51be | ||
|
|
7b27fa70d8 | ||
|
|
372b3aa407 | ||
|
|
bda293bc53 | ||
|
|
11873d06ff | ||
|
|
89ea50b893 | ||
|
|
874b4bb768 | ||
|
|
1e49f52abe | ||
|
|
94088e76ec | ||
|
|
c7abcce729 | ||
|
|
e9d2f4bacc | ||
|
|
7e7965f98e | ||
|
|
d823ae687b | ||
|
|
21a36c0965 | ||
|
|
c3d162b991 | ||
|
|
7e325c5101 | ||
|
|
59ff07fb01 | ||
|
|
2ba92ed3b6 | ||
|
|
418c072414 | ||
|
|
397fe6b7e4 | ||
|
|
97d500028a | ||
|
|
527dfeef9f | ||
|
|
1b3baab691 | ||
|
|
5d512f7806 | ||
|
|
0da525f692 | ||
|
|
d076817c9e | ||
|
|
d2af7c1f5e | ||
|
|
ef002f9186 | ||
|
|
f1006355c4 | ||
|
|
ec6087a03c | ||
|
|
2e465f4d03 | ||
|
|
08bf6654fc | ||
|
|
77e29852a5 | ||
|
|
6bc84d4b25 | ||
|
|
d31e2ab98b | ||
|
|
ee14c34671 | ||
|
|
a8b290692e | ||
|
|
441f911560 | ||
|
|
10090b474a | ||
|
|
aff2594ef2 | ||
|
|
66aad7c488 | ||
|
|
896be9c9c9 | ||
|
|
8d1821e05d | ||
|
|
b7014552d2 | ||
|
|
8561556f5c | ||
|
|
58f7479380 | ||
|
|
7b70c81d4d | ||
|
|
1981f39f9e | ||
|
|
e86ea3e5c4 | ||
|
|
8e01b837a2 | ||
|
|
f33fe84350 | ||
|
|
dbbad817c7 | ||
|
|
0eb0939598 | ||
|
|
65f7855703 | ||
|
|
45d482d347 | ||
|
|
1654dc8678 | ||
|
|
cb417ea76d | ||
|
|
17df4aea35 | ||
|
|
714429d8f4 | ||
|
|
0df03f1d32 | ||
|
|
fefc10afb8 | ||
|
|
1658627069 | ||
|
|
16ab540298 | ||
|
|
4e5afa4747 | ||
|
|
d76ff07bf4 | ||
|
|
b38333bb64 | ||
|
|
f863537190 | ||
|
|
a72a672aaf | ||
|
|
a3dd817e7a | ||
|
|
9d9e07d0fa | ||
|
|
30783d0e5d | ||
|
|
3a296f0f9c | ||
|
|
c0d5a771a5 | ||
|
|
8fc7272e38 | ||
|
|
8b8dc34ba6 | ||
|
|
966145d384 | ||
|
|
2b4060cb7b | ||
|
|
9455a361dc | ||
|
|
26132e23a3 | ||
|
|
5acaadeaae | ||
|
|
324f4b1ffa | ||
|
|
0c02952f7a | ||
|
|
f76a4b37e4 | ||
|
|
f33f93006e | ||
|
|
382756a6f0 | ||
|
|
559bee6ca2 | ||
|
|
190fc651ae | ||
|
|
1c62da4e7c | ||
|
|
8a9d2d7f9a | ||
|
|
ae3be12934 | ||
|
|
4683e0d084 | ||
|
|
c55d3f5350 | ||
|
|
7273d60154 | ||
|
|
587daa5ffe | ||
|
|
064e635d35 | ||
|
|
06db522545 | ||
|
|
e5335c2472 | ||
|
|
a2ec066c6d | ||
|
|
15d4ffc349 | ||
|
|
9af9e45b8a | ||
|
|
f30dd38b96 | ||
|
|
d5f3599b9e | ||
|
|
de62ab535c | ||
|
|
8b8562916b | ||
|
|
0d7b920cbe | ||
|
|
f3254a380f | ||
|
|
0e12029efc | ||
|
|
fd6aa5c6b2 | ||
|
|
5be9db83f7 | ||
|
|
12d6b0bf57 | ||
|
|
961462fe54 | ||
|
|
f0e0103d81 | ||
|
|
755523e07b | ||
|
|
c4ace0697b | ||
|
|
69489c4ee2 | ||
|
|
e05d7468b5 | ||
|
|
1a6a91335e | ||
|
|
80de069c7b | ||
|
|
2de8bbe548 | ||
|
|
7ba2a3bec1 | ||
|
|
89fa2fce23 | ||
|
|
84b47416d6 | ||
|
|
55c72cddba | ||
|
|
6effd4a7d9 | ||
|
|
95f6695d00 | ||
|
|
fde7f0f73b | ||
|
|
dd1bffec09 | ||
|
|
83a951b3af | ||
|
|
6762ed25dc | ||
|
|
6ba869234e | ||
|
|
2c04376a61 | ||
|
|
f180f1fff8 | ||
|
|
ab65ca7a13 | ||
|
|
8895b5062a | ||
|
|
2f4aafb1b3 | ||
|
|
be08c8487a | ||
|
|
0d5df91d2d | ||
|
|
72e4067beb | ||
|
|
ba4f888826 | ||
|
|
82b43eb996 | ||
|
|
777132ec40 | ||
|
|
7f6f60227a | ||
|
|
ab6ff5dbfd | ||
|
|
0d272bc9b7 | ||
|
|
2b08d7801b | ||
|
|
cec4ff6cda | ||
|
|
6f300ba1d5 | ||
|
|
86813629ed | ||
|
|
73a728e606 | ||
|
|
af1228e363 | ||
|
|
f3a2758bcc | ||
|
|
6f9f2f2d34 | ||
|
|
9f4c21a1b1 | ||
|
|
aac0aa755f | ||
|
|
4be77c07ac | ||
|
|
9372906a3e | ||
|
|
e12e521622 | ||
|
|
0082c3a6a8 | ||
|
|
f79973e922 | ||
|
|
59ca45e9b1 | ||
|
|
bb22ec1e88 | ||
|
|
ba315014fa | ||
|
|
8387f56048 | ||
|
|
68acf5f986 | ||
|
|
785dade6b2 |
@@ -6,7 +6,10 @@ APP_URL=http://localhost
|
||||
APP_DEMO=false
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
SCOUT_DRIVER=tntsearch
|
||||
SCOUT_QUEUE=true
|
||||
|
||||
FILESYSTEM_DRIVER=
|
||||
CHUNK_SIZE=128
|
||||
|
||||
@@ -19,7 +22,7 @@ DB_PASSWORD=
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
QUEUE_CONNECTION=sync
|
||||
QUEUE_CONNECTION=database
|
||||
SESSION_DRIVER=file
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
|
||||
3
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
/app/Console/Commands/SetupDevelopmentEnvironment.php
|
||||
/node_modules
|
||||
/public/hot
|
||||
/public/storage
|
||||
@@ -11,8 +12,10 @@
|
||||
.env.backup
|
||||
.phpunit.result.cache
|
||||
.phpstorm.meta.php
|
||||
.vscode/
|
||||
_ide_helper.php
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
prettier.json
|
||||
|
||||
3090
.phpstorm.meta.php
125
README.md
@@ -1,16 +1,6 @@
|
||||

|
||||
# Private Cloud Storage Build on Laravel & Vue.js
|
||||
|
||||
## Supporting VueFileManager
|
||||
Hi, we are trying make the best experience with VueFileManager. There is a lot things to do, and a lot of features we can make.
|
||||
|
||||
But, it can't be done without you, development is more and more complicated and we have to hire new colleagues to help with it. There is couple way you can support us, and then, we support you with all great new features which can be. Thanks you for participating on this awesome software!
|
||||
|
||||
- [Buy me a Coffe](https://www.buymeacoffee.com/pepe)
|
||||
- [One-time donation via PayPal](https://www.paypal.me/peterpapp)
|
||||
- [Become a backer or sponsor on Patreon](https://www.patreon.com/vuefilemanager)
|
||||
- [Purchase Licence on CodeCanyon](https://codecanyon.net/item/vue-file-manager-with-laravel-backend/25815986)
|
||||
|
||||
## Contents
|
||||
|
||||
- [Installation](#installation)
|
||||
@@ -18,13 +8,15 @@ But, it can't be done without you, development is more and more complicated and
|
||||
- [Installation](#installation)
|
||||
- [PHP Configuration](#php-configuration)
|
||||
- [Chunk Upload](#chunk-upload)
|
||||
- [Upgrade Guide](#upgrade-guide)
|
||||
- [Common Instructions](#common-instructions)
|
||||
- [Update from 1.7.12 to 1.8](#update-from-1712-to-18)
|
||||
- [Update from 1.7.10 to 1.7.11](#update-from-1710-to-1711)
|
||||
- [Update from 1.7.8 to 1.7.9](#update-from-178-to-179)
|
||||
- [Update from 1.7.x to 1.7.8](#update-from-17x-to-178)
|
||||
- [Update from 1.6.x to 1.7](#update-from-16x-to-17)
|
||||
- [Nginx Configuration](#nginx-configuration)
|
||||
- [Apache Configuration](#apache-configuration)
|
||||
- [Recover Failed Installation](#installation-failed)
|
||||
- [Update Guide](#update-guide)
|
||||
- [Instructions](#instructions)
|
||||
- [Update from 1.7.x to 1.7.7](#update-from-17x-to-177)
|
||||
- [Update from 1.6.x to 1.7](#update-from-16x-to-17)
|
||||
- [Payments](#payments)
|
||||
- [Get your active plans](#get-your-active-plans)
|
||||
- [Manage Failed Payments](#manage-failed-payments)
|
||||
@@ -51,7 +43,6 @@ But, it can't be done without you, development is more and more complicated and
|
||||
- Nginx or Apache
|
||||
|
||||
|
||||
|
||||
**These PHP Extensions are required:**
|
||||
|
||||
- GD
|
||||
@@ -70,7 +61,7 @@ But, it can't be done without you, development is more and more complicated and
|
||||
## Installation
|
||||
|
||||
#### 1. Upload files on your server
|
||||
Copy project files to web root folder of your domain. It's mostly located in `html`, `www` or `public_html` folder name.
|
||||
Upload project files to web root folder of your domain. It's mostly located in `html`, `www` or `public_html` folder name.
|
||||
|
||||
#### 2. Configure your web root folder
|
||||
Configure your web server's document root to point to the public directory of the files you previously uploaded. For example, if you've uploaded the files in `html` folder, your domain root directory should be changed to `html/project_files/public` folder or anything else where domain root is in project `/public` directory.
|
||||
@@ -104,6 +95,13 @@ At first step you have to verify your purchase code. **Subscription service with
|
||||
|
||||
That was the hardest part of installation proces. Please follow instructions in every step of Setup Wizard to successfully install VueFileManager.
|
||||
|
||||
#### 7. Set up Cron
|
||||
|
||||
Add the following Cron entry to your server. Just update your php path (if it's different) and project path:
|
||||
```
|
||||
* * * * * /usr/local/bin/php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
|
||||
```
|
||||
|
||||
## PHP Configuration
|
||||
There are several PHP settings good to know to setup before you try upload any file. Please set these values in your php.ini, we provide minimal setup for you. When you set `-1` then you set infinity limits.
|
||||
|
||||
@@ -116,10 +114,54 @@ max_execution_time = 3600
|
||||
```
|
||||
|
||||
## Chunk & Multipart Upload
|
||||
VueFileManager in default supporting chunk upload. Default chunk upload size is `128MB`. If you wish change this default value, go to `/config/vuefilemanager.php` and change `chunk_size` attribute.
|
||||
VueFileManager in default supporting chunk upload. Default chunk upload size is `128MB`. If you wish change this default value, go to your `.env` and change `CHUNK_SIZE` attribute.
|
||||
|
||||
When you use external storage, and upload large files, to prevent failing upload process make sure you have enough space in your application space and set higher `max_execution_time` in your php.ini to move your files to external storage.
|
||||
|
||||
## Upgrade Guide
|
||||
|
||||
### Common Instructions
|
||||
`Don't forget create backup of your database before make any changes in your production application. If you serve your files in local storage driver pay attention and don't delete your /storage folder!`
|
||||
|
||||
These instructions is applicable for all updates. Please follow this step:
|
||||
|
||||
- Just rewrite all project files with new excluded `/.env` file and `/storage` folder. These items must be preserved!
|
||||
|
||||
### Update from 1.7.12 to 1.8
|
||||
- Before upload new files to your hosting, log in to VueFileManager as Admin. After uploading new files on your webhosting, visit this url `your-domain.com/service/upgrade-database` for upgrading your database.
|
||||
- Just rewrite all project files with new, excluded /.env file and /storage folder. These items must be preserved!
|
||||
- set **QUEUE_CONNECTION** to **database** in your **.env** file
|
||||
- Clear cache in your administration panel - Settings / Application / Clear Cache
|
||||
|
||||
If you are upgrading from GitHub, don't forget run `composer install` to install new vendors.
|
||||
|
||||
### Update from 1.7.10 to 1.7.11
|
||||
Before upload new files to your hosting, log in to VueFileManager as Admin. After uploading new files on your webhosting, visit this url `your-domain.com/service/upgrade-database` for upgrading your database.
|
||||
|
||||
### Update from 1.7.8 to 1.7.9
|
||||
After rewrited old files with new files, log in as admin to the app and go to `your-domain.com/service/upgrade-database`. This will upgrade your database on the background.
|
||||
|
||||
Add the following Cron entry to your server. Just update your php path (if it's different) and project path:
|
||||
```
|
||||
* * * * * /usr/local/bin/php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
|
||||
```
|
||||
|
||||
### Update from 1.7.x to 1.7.8
|
||||
For those who have installed VueFileManager via git or any other repository synchronization tool, dont't forget after updated code run `composer update` command to update your vendors.
|
||||
|
||||
### Update from 1.6.x to 1.7
|
||||
|
||||
For those, who purchase extended licence, place these lines at the end of your `/.env` file:
|
||||
```
|
||||
CASHIER_LOGGER=stack
|
||||
CASHIER_CURRENCY=
|
||||
STRIPE_KEY=
|
||||
STRIPE_SECRET=
|
||||
STRIPE_WEBHOOK_SECRET=
|
||||
CASHIER_PAYMENT_NOTIFICATION=App\Notifications\ConfirmPayment
|
||||
```
|
||||
|
||||
Then go to https://your-domain.com/upgrade and follow the setup wizard instructions.
|
||||
|
||||
## Nginx Configuration
|
||||
If you running VueFileManager undex Nginx, don't forget set this value in your `nginx.conf` file:
|
||||
@@ -182,44 +224,6 @@ Make sure you have enabled mod_rewrite. There is an example config for running V
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
## Installation Failed
|
||||
|
||||
What to do when installation fail and you can't continue, at first, try to fix issue why installation fail. Probably missing PHP extension or permissions wasn't set correctly.
|
||||
|
||||
At worst scenarios, to reset Setup Wizard, delete all tables in your previously created database, delete content of `/storage/framework/cache`. Then replace content in your `.env` file from `.env.example` file.
|
||||
|
||||
After these steps, installation will be reseted.
|
||||
|
||||
## Update Guide
|
||||
|
||||
### Instructions
|
||||
`Don't forget create backup of your database and storage before make any changes in your production application.`
|
||||
|
||||
`If you serve your files in local storage driver pay attention and don't delete your /storage folder`
|
||||
|
||||
Follow this steps:
|
||||
|
||||
- Make a backup of the .env config file located on your server.
|
||||
- Upload and replace all the files on your server with what's inside the app folder.
|
||||
- Restore your `.env` config file on your server.
|
||||
|
||||
## Update from 1.7.x to 1.7.7
|
||||
If you are upgrading app to 1.7.7 from 1.7.x, make sure you have copied new /vendor folder or if you are using terminal or git, run `composer update` command to update your vendors.
|
||||
|
||||
## Update from 1.6.x to 1.7
|
||||
|
||||
For those, who purchase extended licence, place these lines at the end of your `/.env` file:
|
||||
```
|
||||
CASHIER_LOGGER=stack
|
||||
CASHIER_CURRENCY=
|
||||
STRIPE_KEY=
|
||||
STRIPE_SECRET=
|
||||
STRIPE_WEBHOOK_SECRET=
|
||||
CASHIER_PAYMENT_NOTIFICATION=App\Notifications\ConfirmPayment
|
||||
```
|
||||
|
||||
Then go to https://your-domain.com/upgrade and follow the setup wizard instructions.
|
||||
|
||||
# Payments
|
||||
VueFileManager is packed with **Stripe** payment options. To configure Stripe, you will be asked in Setup Wizard to set up. Or, if you skip this installation process, you will find stripe set up in you admin `Dashboard / Settings / Payments`.
|
||||
|
||||
@@ -359,6 +363,15 @@ The following support channels are available at your fingertips:
|
||||
- [CodeCanyon support message](https://codecanyon.net/item/vue-file-manager-with-laravel-backend/25815986/support)
|
||||
- [GitHub repository](https://vuefilemanager.com/github-access)
|
||||
|
||||
## Supporting VueFileManager
|
||||
Hi, we are trying make the best experience with VueFileManager. There is a lot things to do, and a lot of features we can make.
|
||||
|
||||
But, it can't be done without you, development is more and more complicated and we have to hire new colleagues to help with it. There is couple way you can support us, and then, we support you with all great new features which can be. Thanks you for participating on this awesome software!
|
||||
|
||||
- [Buy me a Coffe](https://www.buymeacoffee.com/pepe)
|
||||
- [Become a Patreon](https://www.patreon.com/vuefilemanager)
|
||||
- [One-time donation via PayPal](https://www.paypal.me/peterpapp)
|
||||
|
||||
## Security Vulnerabilities
|
||||
|
||||
If you discover a security vulnerability within this project, please send an e-mail to [peterpapp@makingcg.com](peterpapp@makingcg.com). All security vulnerabilities will be promptly addressed.
|
||||
|
||||
5854
_ide_helper.php
@@ -3,9 +3,14 @@
|
||||
namespace App\Console;
|
||||
|
||||
use App\Console\Commands\Deploy;
|
||||
|
||||
// use App\Console\Commands\SetupDevelopmentEnvironment;
|
||||
use App\Console\Commands\SetupDevEnvironment;
|
||||
use App\Console\Commands\SetupProductionEnvironment;
|
||||
use App\Console\Commands\UpgradeApp;
|
||||
use App\Share;
|
||||
use App\Zip;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
@@ -18,18 +23,29 @@ class Kernel extends ConsoleKernel
|
||||
*/
|
||||
protected $commands = [
|
||||
Deploy::class,
|
||||
// SetupDevelopmentEnvironment::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
// $schedule->command('inspire')
|
||||
// ->hourly();
|
||||
$schedule->call(function () {
|
||||
$this->delete_expired_shared_links();
|
||||
})->everyMinute();
|
||||
|
||||
$schedule->call(function () {
|
||||
$this->delete_old_zips();
|
||||
})->everySixHours();
|
||||
|
||||
// Run queue jobs every minute
|
||||
$schedule->command('queue:work --tries=3')
|
||||
->everyMinute()
|
||||
->withoutOverlapping();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,8 +55,46 @@ class Kernel extends ConsoleKernel
|
||||
*/
|
||||
protected function commands()
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
$this->load(__DIR__ . '/Commands');
|
||||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete old zips
|
||||
*/
|
||||
protected function delete_old_zips(): void
|
||||
{
|
||||
// Get all zips
|
||||
$zips = Zip::where('created_at', '<=', Carbon::now()->subDay()->toDateTimeString())->get();
|
||||
|
||||
$zips->each(function ($zip) {
|
||||
|
||||
// Delete zip file
|
||||
\Storage::disk('local')->delete('zip/' . $zip->basename);
|
||||
|
||||
// Delete zip record
|
||||
$zip->delete();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and delete expired shared links
|
||||
*/
|
||||
protected function delete_expired_shared_links(): void
|
||||
{
|
||||
// Get all shares with expiration time
|
||||
$shares = Share::whereNotNull('expire_in')->get();
|
||||
|
||||
$shares->each(function ($share) {
|
||||
|
||||
// Get dates
|
||||
$created_at = Carbon::parse($share->created_at);
|
||||
|
||||
// If time was over, then delete share record
|
||||
if ($created_at->diffInHours(Carbon::now()) >= $share->expire_in) {
|
||||
$share->delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ use Illuminate\Support\Str;
|
||||
use Laravel\Scout\Searchable;
|
||||
use TeamTNT\TNTSearch\Indexer\TNTIndexer;
|
||||
use \Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Kyslik\ColumnSortable\Sortable;
|
||||
|
||||
/**
|
||||
* App\FileManagerFile
|
||||
@@ -52,10 +53,13 @@ use \Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\FileManagerFile withTrashed()
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\FileManagerFile withoutTrashed()
|
||||
* @mixin \Eloquent
|
||||
* @property array|null $metadata
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileManagerFile sortable($defaultParameters = null)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileManagerFile whereMetadata($value)
|
||||
*/
|
||||
class FileManagerFile extends Model
|
||||
{
|
||||
use Searchable, SoftDeletes;
|
||||
use Searchable, SoftDeletes , Sortable;
|
||||
|
||||
public $public_access = null;
|
||||
|
||||
@@ -67,6 +71,20 @@ class FileManagerFile extends Model
|
||||
'file_url'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'metadata' => 'array',
|
||||
];
|
||||
|
||||
/**
|
||||
* Sortable columns
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public $sortable = [
|
||||
'name',
|
||||
'created_at',
|
||||
];
|
||||
|
||||
/**
|
||||
* Set routes with public access
|
||||
*
|
||||
@@ -84,7 +102,7 @@ class FileManagerFile extends Model
|
||||
*/
|
||||
public function getCreatedAtAttribute()
|
||||
{
|
||||
return format_date($this->attributes['created_at'], __('vuefilemanager.time'));
|
||||
return format_date(set_time_by_user_timezone($this->attributes['created_at']), __('vuefilemanager.time'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,7 +114,7 @@ class FileManagerFile extends Model
|
||||
{
|
||||
if (!$this->attributes['deleted_at']) return null;
|
||||
|
||||
return format_date($this->attributes['deleted_at'], __('vuefilemanager.time'));
|
||||
return format_date(set_time_by_user_timezone($this->attributes['deleted_at']), __('vuefilemanager.time'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,7 +166,9 @@ class FileManagerFile extends Model
|
||||
// Get file from external storage
|
||||
if (is_storage_driver(['s3', 'spaces', 'wasabi', 'backblaze'])) {
|
||||
|
||||
$file_pretty_name = get_pretty_name($this->attributes['basename'], $this->attributes['name'], $this->attributes['mimetype']);
|
||||
$file_pretty_name = is_storage_driver('backblaze')
|
||||
? Str::snake(mb_strtolower($this->attributes['name']))
|
||||
: get_pretty_name($this->attributes['basename'], $this->attributes['name'], $this->attributes['mimetype']);
|
||||
|
||||
$header = [
|
||||
"ResponseAcceptRanges" => "bytes",
|
||||
|
||||
@@ -11,6 +11,7 @@ use RecursiveArrayIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use TeamTNT\TNTSearch\Indexer\TNTIndexer;
|
||||
use \Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Kyslik\ColumnSortable\Sortable;
|
||||
|
||||
/**
|
||||
* App\FileManagerFolder
|
||||
@@ -58,10 +59,11 @@ use \Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\FileManagerFolder withTrashed()
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\FileManagerFolder withoutTrashed()
|
||||
* @mixin \Eloquent
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileManagerFolder sortable($defaultParameters = null)
|
||||
*/
|
||||
class FileManagerFolder extends Model
|
||||
{
|
||||
use Searchable, SoftDeletes;
|
||||
use Searchable, SoftDeletes , Sortable;
|
||||
|
||||
protected $guarded = [
|
||||
'id'
|
||||
@@ -71,6 +73,20 @@ class FileManagerFolder extends Model
|
||||
'items', 'trashed_items'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'icon_emoji' => 'object',
|
||||
];
|
||||
|
||||
/**
|
||||
* Sortable columns
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public $sortable = [
|
||||
'name',
|
||||
'created_at',
|
||||
];
|
||||
|
||||
/**
|
||||
* Index folder
|
||||
*
|
||||
@@ -121,7 +137,7 @@ class FileManagerFolder extends Model
|
||||
*/
|
||||
public function getCreatedAtAttribute()
|
||||
{
|
||||
return format_date($this->attributes['created_at'], __('vuefilemanager.time'));
|
||||
return format_date(set_time_by_user_timezone($this->attributes['created_at']), __('vuefilemanager.time'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,7 +149,7 @@ class FileManagerFolder extends Model
|
||||
{
|
||||
if (! $this->attributes['deleted_at']) return null;
|
||||
|
||||
return format_date($this->attributes['deleted_at'], __('vuefilemanager.time'));
|
||||
return format_date(set_time_by_user_timezone($this->attributes['deleted_at']), __('vuefilemanager.time'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -85,8 +85,8 @@ class UserController extends Controller
|
||||
{
|
||||
$user = User::find($id);
|
||||
|
||||
if (! $user->stripeId()) {
|
||||
return response('User is not stripe customer', 404);
|
||||
if (! $user->stripeId() || ! $user->subscription('main')) {
|
||||
return response('User doesn\'t have any subscription.', 404);
|
||||
}
|
||||
|
||||
return new UserSubscription(
|
||||
@@ -102,7 +102,7 @@ class UserController extends Controller
|
||||
public function users()
|
||||
{
|
||||
return new UsersCollection(
|
||||
User::sortable()->paginate('20')
|
||||
User::sortable(['created_at', 'DESC'])->paginate('20')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,15 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Content;
|
||||
use App\FileManagerFile;
|
||||
use App\FileManagerFolder;
|
||||
use App\Http\Requests\PublicPages\SendMessageRequest;
|
||||
use App\Http\Resources\PageResource;
|
||||
use App\Http\Tools\Demo;
|
||||
use App\Mail\SendSupportForm;
|
||||
use App\Page;
|
||||
use App\Setting;
|
||||
use App\User;
|
||||
use Artisan;
|
||||
use Doctrine\DBAL\Driver\PDOException;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -23,6 +26,7 @@ class AppFunctionsController extends Controller
|
||||
* @var array
|
||||
*/
|
||||
private $whitelist = [
|
||||
'section_features',
|
||||
'footer_content',
|
||||
'get_started_description',
|
||||
'get_started_title',
|
||||
@@ -41,7 +45,7 @@ class AppFunctionsController extends Controller
|
||||
'section_get_started',
|
||||
'section_pricing_content',
|
||||
'section_feature_boxes',
|
||||
'section_features',
|
||||
'allow_homepage',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -96,6 +100,68 @@ class AppFunctionsController extends Controller
|
||||
->with('installation', $connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get og site for web crawlers
|
||||
*
|
||||
* @param $token
|
||||
*/
|
||||
public function og_site($token)
|
||||
{
|
||||
// Get all settings
|
||||
$settings = Setting::all();
|
||||
|
||||
// Get shared token
|
||||
$shared = get_shared($token);
|
||||
|
||||
// Get user
|
||||
$user = User::findOrFail($shared->user_id);
|
||||
|
||||
// Handle single file
|
||||
if ($shared->type === 'file') {
|
||||
|
||||
// Get file record
|
||||
$file = FileManagerFile::where('user_id', $shared->user_id)
|
||||
->where('unique_id', $shared->item_id)
|
||||
->first();
|
||||
|
||||
if ($file->thumbnail) {
|
||||
$file->setPublicUrl($token);
|
||||
}
|
||||
|
||||
$metadata = [
|
||||
'is_protected' => $shared->protected,
|
||||
'url' => url('/shared', ['token' => $token]),
|
||||
'user' => $user->name,
|
||||
'name' => $file->name,
|
||||
'size' => $file->filesize,
|
||||
'thumbnail' => $file->thumbnail ? $file->thumbnail : null,
|
||||
];
|
||||
}
|
||||
|
||||
// Handle single file
|
||||
if ($shared->type === 'folder') {
|
||||
|
||||
// Get file record
|
||||
$folder = FileManagerFolder::where('user_id', $shared->user_id)
|
||||
->where('unique_id', $shared->item_id)
|
||||
->first();
|
||||
|
||||
$metadata = [
|
||||
'is_protected' => $shared->protected,
|
||||
'url' => url('/shared', ['token' => $token]),
|
||||
'user' => $user->name,
|
||||
'name' => $folder->name,
|
||||
'size' => $folder->items,
|
||||
'thumbnail' => null,
|
||||
];
|
||||
}
|
||||
|
||||
// Return view
|
||||
return view("og-view")
|
||||
->with('settings', json_decode($settings->pluck('value', 'name')->toJson()))
|
||||
->with('metadata', $metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if setup wizard was passed
|
||||
*
|
||||
@@ -180,4 +246,16 @@ class AppFunctionsController extends Controller
|
||||
Artisan::call('config:clear');
|
||||
Artisan::call('config:cache');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Emojis List from the server
|
||||
*
|
||||
* @return $emojisList
|
||||
*/
|
||||
public function get_emojis_list()
|
||||
{
|
||||
$emojisList = json_decode(file_get_contents(public_path('assets/emojis.json'), true));
|
||||
|
||||
return collect([$emojisList]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\FileManagerFolder;
|
||||
use App\Http\Tools\Editor;
|
||||
use App\Http\Tools\Guardian;
|
||||
use App\Share;
|
||||
use App\User;
|
||||
use App\Zip;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -13,7 +16,11 @@ use Illuminate\Http\Request;
|
||||
use App\FileManagerFile;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Http\Exceptions\HttpResponseException;
|
||||
use Madnest\Madzipper\Facades\Madzipper;
|
||||
use Response;
|
||||
use League\Flysystem\FileNotFoundException;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
class FileAccessController extends Controller
|
||||
{
|
||||
@@ -84,9 +91,63 @@ class FileAccessController extends Controller
|
||||
$this->check_file_access($shared, $file);
|
||||
}
|
||||
|
||||
// Store user download size
|
||||
$request->user()->record_download((int)$file->getRawOriginal('filesize'));
|
||||
|
||||
return $this->download_file($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get generated zip for user
|
||||
*
|
||||
* @param $id
|
||||
* @return \Symfony\Component\HttpFoundation\StreamedResponse
|
||||
*/
|
||||
public function get_zip($id)
|
||||
{
|
||||
$zip = Zip::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->first();
|
||||
|
||||
$zip_path = 'zip/' . $zip->basename;
|
||||
|
||||
$header = [
|
||||
"Content-Type" => 'application/zip',
|
||||
"Content-Length" => Storage::disk('local')->size($zip_path),
|
||||
"Accept-Ranges" => "bytes",
|
||||
"Content-Range" => "bytes 0-600/" . Storage::disk('local')->size($zip_path),
|
||||
"Content-Disposition" => "attachment; filename=" . $zip->basename,
|
||||
];
|
||||
|
||||
return Storage::disk('local')->download($zip_path, $zip->basename, $header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get generated zip for guest
|
||||
*
|
||||
* @param $id
|
||||
* @param $token
|
||||
* @return \Symfony\Component\HttpFoundation\StreamedResponse
|
||||
*/
|
||||
public function get_zip_public($id, $token)
|
||||
{
|
||||
$zip = Zip::where('id', $id)
|
||||
->where('shared_token', $token)
|
||||
->first();
|
||||
|
||||
$zip_path = 'zip/' . $zip->basename;
|
||||
|
||||
$header = [
|
||||
"Content-Type" => 'application/zip',
|
||||
"Content-Length" => Storage::disk('local')->size($zip_path),
|
||||
"Accept-Ranges" => "bytes",
|
||||
"Content-Range" => "bytes 0-600/" . Storage::disk('local')->size($zip_path),
|
||||
"Content-Disposition" => "attachment; filename=" . $zip->basename,
|
||||
];
|
||||
|
||||
return Storage::disk('local')->download($zip_path, $zip->basename, $header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file public
|
||||
*
|
||||
@@ -101,7 +162,7 @@ class FileAccessController extends Controller
|
||||
$shared = get_shared($token);
|
||||
|
||||
// Abort if shared is protected
|
||||
if ((int) $shared->protected) {
|
||||
if ((int)$shared->protected) {
|
||||
abort(403, "Sorry, you don't have permission");
|
||||
}
|
||||
|
||||
@@ -113,6 +174,9 @@ class FileAccessController extends Controller
|
||||
// Check file access
|
||||
$this->check_file_access($shared, $file);
|
||||
|
||||
// Store user download size
|
||||
User::find($shared->user_id)->record_download((int)$file->getRawOriginal('filesize'));
|
||||
|
||||
return $this->download_file($file);
|
||||
}
|
||||
|
||||
@@ -154,7 +218,7 @@ class FileAccessController extends Controller
|
||||
$shared = get_shared($token);
|
||||
|
||||
// Abort if thumbnail is protected
|
||||
if ((int) $shared->protected) {
|
||||
if ((int)$shared->protected) {
|
||||
abort(403, "Sorry, you don't have permission");
|
||||
}
|
||||
|
||||
@@ -205,15 +269,15 @@ class FileAccessController extends Controller
|
||||
// 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),
|
||||
$headers = [
|
||||
"Accept-Ranges" => "bytes",
|
||||
"Content-Type" => Storage::mimeType($path),
|
||||
"Content-Length" => Storage::size($path),
|
||||
"Content-Range" => "bytes 0-600/" . Storage::size($path),
|
||||
"Content-Disposition" => "attachment; filename=" . $file_pretty_name,
|
||||
];
|
||||
|
||||
// Get file
|
||||
return Storage::download($path, $file_pretty_name, $header);
|
||||
return response()->download(config('filesystems.disks.local.root') . '/file-manager/' . $file->basename, $file_pretty_name, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,6 +36,7 @@ class BrowseController extends Controller
|
||||
->with(['parent'])
|
||||
->where('user_id', $user_id)
|
||||
->whereIn('unique_id', filter_folders_ids($folders_trashed))
|
||||
->sortable()
|
||||
->get();
|
||||
|
||||
// Get files trashed
|
||||
@@ -43,6 +44,7 @@ class BrowseController extends Controller
|
||||
->with(['parent'])
|
||||
->where('user_id', $user_id)
|
||||
->whereNotIn('folder_id', array_values(array_unique(recursiveFind($folders_trashed->toArray(), 'unique_id'))))
|
||||
->sortable()
|
||||
->get();
|
||||
|
||||
// Collect folders and files to single array
|
||||
@@ -69,14 +71,16 @@ class BrowseController extends Controller
|
||||
->pluck('item_id');
|
||||
|
||||
// Get folders and files
|
||||
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected'])
|
||||
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
|
||||
->where('user_id', $user_id)
|
||||
->whereIn('unique_id', $folder_ids)
|
||||
->sortable()
|
||||
->get();
|
||||
|
||||
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected'])
|
||||
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
|
||||
->where('user_id', $user_id)
|
||||
->whereIn('unique_id', $file_ids)
|
||||
->sortable()
|
||||
->get();
|
||||
|
||||
// Collect folders and files to single array
|
||||
@@ -91,7 +95,9 @@ class BrowseController extends Controller
|
||||
public function latest() {
|
||||
|
||||
// Get User
|
||||
$user = User::with(['latest_uploads'])
|
||||
$user = User::with(['latest_uploads' => function($query) {
|
||||
$query->sortable(['created_at' => 'desc']);
|
||||
}])
|
||||
->where('id', Auth::id())
|
||||
->first();
|
||||
|
||||
@@ -106,8 +112,11 @@ class BrowseController extends Controller
|
||||
public function participant_uploads() {
|
||||
|
||||
// Get User
|
||||
$uploads = FileManagerFile::with(['parent'])->where('user_id', Auth::id())
|
||||
->whereUserScope('editor')->orderBy('created_at', 'DESC')->get();
|
||||
$uploads = FileManagerFile::with(['parent'])
|
||||
->where('user_id', Auth::id())
|
||||
->whereUserScope('editor')
|
||||
->sortable()
|
||||
->get();
|
||||
|
||||
return $uploads;
|
||||
}
|
||||
@@ -132,12 +141,14 @@ class BrowseController extends Controller
|
||||
->with('parent')
|
||||
->where('user_id', $user_id)
|
||||
->where('parent_id', $unique_id)
|
||||
->sortable()
|
||||
->get();
|
||||
|
||||
$files = FileManagerFile::onlyTrashed()
|
||||
->with('parent')
|
||||
->where('user_id', $user_id)
|
||||
->where('folder_id', $unique_id)
|
||||
->sortable()
|
||||
->get();
|
||||
|
||||
// Collect folders and files to single array
|
||||
@@ -145,16 +156,16 @@ class BrowseController extends Controller
|
||||
}
|
||||
|
||||
// Get folders and files
|
||||
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected'])
|
||||
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
|
||||
->where('user_id', $user_id)
|
||||
->where('parent_id', $unique_id)
|
||||
->orderBy('created_at', 'DESC')
|
||||
->sortable()
|
||||
->get();
|
||||
|
||||
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected'])
|
||||
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
|
||||
->where('user_id', $user_id)
|
||||
->where('folder_id', $unique_id)
|
||||
->orderBy('created_at', 'DESC')
|
||||
->sortable()
|
||||
->get();
|
||||
|
||||
// Collect folders and files to single array
|
||||
@@ -171,6 +182,7 @@ class BrowseController extends Controller
|
||||
$folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
|
||||
->where('parent_id', 0)
|
||||
->where('user_id', Auth::id())
|
||||
->sortable()
|
||||
->get(['id', 'parent_id', 'unique_id', 'name']);
|
||||
|
||||
return [
|
||||
@@ -193,33 +205,17 @@ class BrowseController extends Controller
|
||||
{
|
||||
// Get user
|
||||
$user_id = Auth::id();
|
||||
$query = remove_accents($request->input('query'));
|
||||
|
||||
// Search files id db
|
||||
$searched_files = FileManagerFile::search($request->input('query'))
|
||||
$searched_files = FileManagerFile::search($query)
|
||||
->where('user_id', $user_id)
|
||||
->get();
|
||||
$searched_folders = FileManagerFolder::search($request->input('query'))
|
||||
$searched_folders = FileManagerFolder::search($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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,12 @@ use App\Http\Requests\FileFunctions\UploadRequest;
|
||||
use App\Http\Tools\Demo;
|
||||
use Illuminate\Contracts\Routing\ResponseFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Tools\Guardian;
|
||||
use App\Http\Tools\Editor;
|
||||
use App\FileManagerFolder;
|
||||
use App\FileManagerFile;
|
||||
use Exception;
|
||||
|
||||
@@ -113,6 +115,12 @@ class EditItemsController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
// If request have a change folder icon values set the folder icon
|
||||
if ($request->type === 'folder' && $request->filled('folder_icon')) {
|
||||
|
||||
Editor::set_folder_icon($request->folder_icon, $unique_id);
|
||||
}
|
||||
|
||||
// Rename Item
|
||||
return Editor::rename_item($request, $unique_id);
|
||||
}
|
||||
@@ -149,6 +157,12 @@ class EditItemsController extends Controller
|
||||
Guardian::check_item_access($item->folder_id, $shared);
|
||||
}
|
||||
|
||||
// If request have a change folder icon values set the folder icon
|
||||
if ($request->type === 'folder' && $request->filled('folder_icon')) {
|
||||
|
||||
Editor::set_folder_icon($request->folder_icon, $unique_id, $shared);
|
||||
}
|
||||
|
||||
// Rename item
|
||||
$item = Editor::rename_item($request, $unique_id, $shared);
|
||||
|
||||
@@ -168,40 +182,43 @@ class EditItemsController extends Controller
|
||||
* @return ResponseFactory|\Illuminate\Http\Response
|
||||
* @throws Exception
|
||||
*/
|
||||
public function user_delete_item(DeleteItemRequest $request, $unique_id)
|
||||
public function user_delete_item(DeleteItemRequest $request)
|
||||
{
|
||||
// Demo preview
|
||||
if (is_demo(Auth::id())) {
|
||||
return Demo::response_204();
|
||||
}
|
||||
|
||||
// Check permission to delete item for authenticated editor
|
||||
if ($request->user()->tokenCan('editor')) {
|
||||
foreach ($request->input('data') as $file) {
|
||||
$unique_id = $file['unique_id'];
|
||||
|
||||
// Prevent force delete for non-master users
|
||||
if ($request->input('data.force_delete')) abort('401');
|
||||
// Check permission to delete item for authenticated editor
|
||||
if ($request->user()->tokenCan('editor')) {
|
||||
|
||||
// check if shared_token cookie exist
|
||||
if (!$request->hasCookie('shared_token')) abort('401');
|
||||
// Prevent force delete for non-master users
|
||||
if ($file['force_delete']) abort('401');
|
||||
|
||||
// Get shared token
|
||||
$shared = get_shared($request->cookie('shared_token'));
|
||||
// check if shared_token cookie exist
|
||||
if (!$request->hasCookie('shared_token')) abort('401');
|
||||
|
||||
// Get file|folder item
|
||||
$item = get_item($request->input('data.type'), $unique_id, Auth::id());
|
||||
// Get shared token
|
||||
$shared = get_shared($request->cookie('shared_token'));
|
||||
|
||||
// Check access to requested directory
|
||||
if ($request->input('data.type') === 'folder') {
|
||||
Guardian::check_item_access($item->unique_id, $shared);
|
||||
} else {
|
||||
Guardian::check_item_access($item->folder_id, $shared);
|
||||
// Get file|folder item
|
||||
$item = get_item($file['type'], $unique_id, Auth::id());
|
||||
|
||||
// Check access to requested directory
|
||||
if ($file['type'] === 'folder') {
|
||||
Guardian::check_item_access($item->unique_id, $shared);
|
||||
} else {
|
||||
Guardian::check_item_access($item->folder_id, $shared);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete item
|
||||
Editor::delete_item($file, $unique_id);
|
||||
}
|
||||
|
||||
// Delete item
|
||||
Editor::delete_item($request, $unique_id);
|
||||
|
||||
// Return response
|
||||
return response(null, 204);
|
||||
}
|
||||
|
||||
@@ -214,7 +231,7 @@ class EditItemsController extends Controller
|
||||
* @return ResponseFactory|\Illuminate\Http\Response
|
||||
* @throws Exception
|
||||
*/
|
||||
public function guest_delete_item(DeleteItemRequest $request, $unique_id, $token)
|
||||
public function guest_delete_item(DeleteItemRequest $request, $token)
|
||||
{
|
||||
// Get shared record
|
||||
$shared = get_shared($token);
|
||||
@@ -227,19 +244,22 @@ class EditItemsController extends Controller
|
||||
// Check shared permission
|
||||
if (!is_editor($shared)) abort(403);
|
||||
|
||||
// Get file|folder item
|
||||
$item = get_item($request->input('data.type'), $unique_id, $shared->user_id);
|
||||
foreach ($request->input('data') as $file) {
|
||||
$unique_id = $file['unique_id'];
|
||||
|
||||
// Check access to requested item
|
||||
if ($request->input('data.type') === 'folder') {
|
||||
Guardian::check_item_access($item->unique_id, $shared);
|
||||
} else {
|
||||
Guardian::check_item_access($item->folder_id, $shared);
|
||||
// Get file|folder item
|
||||
$item = get_item($file['type'], $unique_id, $shared->user_id);
|
||||
|
||||
// Check access to requested item
|
||||
if ($file['type'] === 'folder') {
|
||||
Guardian::check_item_access($item->unique_id, $shared);
|
||||
} else {
|
||||
Guardian::check_item_access($item->folder_id, $shared);
|
||||
}
|
||||
|
||||
// Delete item
|
||||
Editor::delete_item($file, $unique_id, $shared);
|
||||
}
|
||||
|
||||
// Delete item
|
||||
Editor::delete_item($request, $unique_id, $shared);
|
||||
|
||||
// Return response
|
||||
return response(null, 204);
|
||||
}
|
||||
@@ -308,21 +328,19 @@ class EditItemsController extends Controller
|
||||
return $new_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move item for authenticated master|editor user
|
||||
|
||||
/**
|
||||
* User download folder via zip
|
||||
*
|
||||
* @param MoveItemRequest $request
|
||||
* @param $unique_id
|
||||
* @return ResponseFactory|\Illuminate\Http\Response
|
||||
* @return string
|
||||
*/
|
||||
public function user_move(MoveItemRequest $request, $unique_id)
|
||||
public function user_zip_folder(Request $request,$unique_id)
|
||||
{
|
||||
// Demo preview
|
||||
if (is_demo(Auth::id())) {
|
||||
return Demo::response_204();
|
||||
}
|
||||
|
||||
// Check permission to upload for authenticated editor
|
||||
// Get user id
|
||||
$user_id = Auth::id();
|
||||
|
||||
// Check permission to download for authenticated editor
|
||||
if ($request->user()->tokenCan('editor')) {
|
||||
|
||||
// check if shared_token cookie exist
|
||||
@@ -332,11 +350,172 @@ class EditItemsController extends Controller
|
||||
$shared = get_shared($request->cookie('shared_token'));
|
||||
|
||||
// Check access to requested directory
|
||||
Guardian::check_item_access($request->to_unique_id, $shared);
|
||||
Guardian::check_item_access($unique_id, $shared);
|
||||
}
|
||||
|
||||
// Get folder
|
||||
$folder = FileManagerFolder::whereUserId($user_id)
|
||||
->where('unique_id', $unique_id);
|
||||
|
||||
if (! $folder->exists()) {
|
||||
abort(404, 'Requested folder doesn\'t exists.');
|
||||
}
|
||||
|
||||
$zip = Editor::zip_folder($unique_id);
|
||||
|
||||
// Get file
|
||||
return response([
|
||||
'url' => route('zip', $zip->id),
|
||||
'name' => $zip->basename,
|
||||
], 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Guest download folder via zip
|
||||
*
|
||||
* @param Request $request
|
||||
* @param $unique_id
|
||||
* @param $token
|
||||
* @return string
|
||||
*/
|
||||
public function guest_zip_folder($unique_id, $token)
|
||||
{
|
||||
// Get shared record
|
||||
$shared = get_shared($token);
|
||||
|
||||
// Check access to requested folder
|
||||
Guardian::check_item_access($unique_id, $shared);
|
||||
|
||||
// Get folder
|
||||
$folder = FileManagerFolder::whereUserId($shared->user_id)
|
||||
->where('unique_id', $unique_id);
|
||||
|
||||
|
||||
if (! $folder->exists()) {
|
||||
abort(404, 'Requested folder doesn\'t exists.');
|
||||
}
|
||||
|
||||
$zip = Editor::zip_folder($unique_id, $shared);
|
||||
|
||||
// Get file
|
||||
return response([
|
||||
'url' => route('zip_public', [
|
||||
'id' => $zip->id,
|
||||
'token' => $shared->token,
|
||||
]),
|
||||
'name' => $zip->basename,
|
||||
], 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* User download multiple files via zip
|
||||
*
|
||||
* @param Request $request
|
||||
* @return string
|
||||
*/
|
||||
public function user_zip_multiple_files(Request $request)
|
||||
{
|
||||
// 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'));
|
||||
|
||||
$file_parent_folders = FileManagerFile::whereUserId(Auth::id())
|
||||
->whereIn('unique_id', $request->input('files'))
|
||||
->get()
|
||||
->pluck('folder_id')
|
||||
->toArray();
|
||||
|
||||
// Check access to requested directory
|
||||
Guardian::check_item_access($file_parent_folders, $shared);
|
||||
}
|
||||
|
||||
// Get requested files
|
||||
$files = FileManagerFile::whereUserId(Auth::id())
|
||||
->whereIn('unique_id', $request->input('files'))
|
||||
->get();
|
||||
|
||||
$zip = Editor::zip_files($files);
|
||||
|
||||
// Get file
|
||||
return response([
|
||||
'url' => route('zip', $zip->id),
|
||||
'name' => $zip->basename,
|
||||
], 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Guest download multiple files via zip
|
||||
*
|
||||
* @param Request $request
|
||||
* @param $token
|
||||
* @return string
|
||||
*/
|
||||
public function guest_zip_multiple_files(Request $request, $token)
|
||||
{
|
||||
// Get shared record
|
||||
$shared = get_shared($token);
|
||||
|
||||
$file_parent_folders = FileManagerFile::whereUserId($shared->user_id)
|
||||
->whereIn('unique_id', $request->input('files'))
|
||||
->get()
|
||||
->pluck('folder_id')
|
||||
->toArray();
|
||||
|
||||
// Check access to requested directory
|
||||
Guardian::check_item_access($file_parent_folders, $shared);
|
||||
|
||||
// Get requested files
|
||||
$files = FileManagerFile::whereUserId($shared->user_id)
|
||||
->whereIn('unique_id', $request->input('files'))
|
||||
->get();
|
||||
|
||||
$zip = Editor::zip_files($files, $shared);
|
||||
|
||||
// Get file
|
||||
return response([
|
||||
'url' => route('zip_public', [
|
||||
'id' => $zip->id,
|
||||
'token' => $shared->token,
|
||||
]),
|
||||
'name' => $zip->basename,
|
||||
], 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move item for authenticated master|editor user
|
||||
*
|
||||
* @param MoveItemRequest $request
|
||||
* @param $unique_id
|
||||
* @return ResponseFactory|\Illuminate\Http\Response
|
||||
*/
|
||||
public function user_move(MoveItemRequest $request)
|
||||
{
|
||||
// Demo preview
|
||||
if (is_demo(Auth::id())) {
|
||||
return Demo::response_204();
|
||||
}
|
||||
|
||||
$to_unique_id = $request->input('to_unique_id');
|
||||
|
||||
// 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($to_unique_id, $shared);
|
||||
}
|
||||
|
||||
// Move item
|
||||
Editor::move($request, $unique_id);
|
||||
Editor::move($request, $to_unique_id);
|
||||
|
||||
return response('Done!', 204);
|
||||
}
|
||||
@@ -349,11 +528,14 @@ class EditItemsController extends Controller
|
||||
* @param $token
|
||||
* @return ResponseFactory|\Illuminate\Http\Response
|
||||
*/
|
||||
public function guest_move(MoveItemRequest $request, $unique_id, $token)
|
||||
public function guest_move(MoveItemRequest $request, $token)
|
||||
{
|
||||
// Get shared record
|
||||
$shared = get_shared($token);
|
||||
|
||||
//Unique id of Folder where move
|
||||
$to_unique_id = $request->input('to_unique_id');
|
||||
|
||||
// Demo preview
|
||||
if (is_demo(Auth::id())) {
|
||||
return Demo::response_204();
|
||||
@@ -362,23 +544,28 @@ class EditItemsController extends Controller
|
||||
// Check shared permission
|
||||
if (!is_editor($shared)) abort(403);
|
||||
|
||||
$moving_unique_id = $unique_id;
|
||||
foreach ($request->input('items') as $item) {
|
||||
|
||||
if ($request->from_type !== 'folder') {
|
||||
$file = FileManagerFile::where('unique_id', $unique_id)
|
||||
->where('user_id', $shared->user_id)
|
||||
->firstOrFail();
|
||||
$unique_id = $item['unique_id'];
|
||||
$moving_unique_id = $unique_id;
|
||||
|
||||
$moving_unique_id = $file->folder_id;
|
||||
|
||||
if ($item['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([
|
||||
$to_unique_id, $moving_unique_id
|
||||
], $shared);
|
||||
}
|
||||
|
||||
// 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);
|
||||
Editor::move($request, $to_unique_id, $shared);
|
||||
|
||||
return response('Done!', 204);
|
||||
}
|
||||
|
||||
@@ -20,16 +20,18 @@ class FavouriteController extends Controller
|
||||
public function store(Request $request)
|
||||
{
|
||||
// Validate request
|
||||
$validator = Validator::make($request->all(), [
|
||||
'unique_id' => 'required|integer',
|
||||
$validator = Validator::make($request->input('folders'), [
|
||||
'*.unique_id' => 'required|integer',
|
||||
]);
|
||||
|
||||
// Return error
|
||||
if ($validator->fails()) abort(400, 'Bad input');
|
||||
|
||||
foreach($request->input('folders') as $item) {
|
||||
|
||||
// Get user & folder
|
||||
$user = Auth::user();
|
||||
$folder = FileManagerFolder::where('unique_id', $request->unique_id)->first();
|
||||
$folder = FileManagerFolder::where('unique_id', $item['unique_id'])->first();
|
||||
|
||||
if (is_demo($user->id)) {
|
||||
return Demo::favourites($user);
|
||||
@@ -39,8 +41,9 @@ class FavouriteController extends Controller
|
||||
if ($folder->user_id !== $user->id) abort(403);
|
||||
|
||||
// Add folder to user favourites
|
||||
$user->favourite_folders()->syncWithoutDetaching($request->unique_id);
|
||||
$user->favourite_folders()->syncWithoutDetaching($item['unique_id']);
|
||||
|
||||
}
|
||||
// Return updated favourites
|
||||
return $user->favourite_folders;
|
||||
}
|
||||
|
||||
@@ -5,14 +5,18 @@ namespace App\Http\Controllers\FileFunctions;
|
||||
use App\Http\Requests\Share\CreateShareRequest;
|
||||
use App\Http\Requests\Share\UpdateShareRequest;
|
||||
use App\Http\Resources\ShareResource;
|
||||
use App\Notifications\SharedSendViaEmail;
|
||||
use App\Zip;
|
||||
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\Facades\Notification;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Share;
|
||||
use Validator;
|
||||
|
||||
class ShareController extends Controller
|
||||
{
|
||||
@@ -51,12 +55,23 @@ class ShareController extends Controller
|
||||
'protected' => $request->isPassword,
|
||||
'permission' => $request->permission,
|
||||
'item_id' => $request->unique_id,
|
||||
'expire_in' => $request->expiration,
|
||||
'user_id' => Auth::id(),
|
||||
'token' => $token,
|
||||
];
|
||||
|
||||
// Return created shared record
|
||||
return new ShareResource(Share::create($options));
|
||||
$share = new ShareResource(Share::create($options));
|
||||
|
||||
// Send shared link via email
|
||||
if ($request->has('emails')) {
|
||||
|
||||
foreach ($request->emails as $email) {
|
||||
Notification::route('mail', $email)->notify(new SharedSendViaEmail($token));
|
||||
}
|
||||
}
|
||||
|
||||
return $share;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,6 +92,7 @@ class ShareController extends Controller
|
||||
$shared->update([
|
||||
'permission' => $request->permission,
|
||||
'protected' => $request->protected,
|
||||
'expire_in' => $request->expiration,
|
||||
'password' => $request->password ? Hash::make($request->password) : $shared->password,
|
||||
]);
|
||||
|
||||
@@ -91,17 +107,53 @@ class ShareController extends Controller
|
||||
* @return ResponseFactory|\Illuminate\Http\Response
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function destroy($token)
|
||||
public function destroy(Request $request)
|
||||
{
|
||||
// Get sharing record
|
||||
$shared = Share::where('token', $token)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
foreach ($request->input('tokens') as $token) {
|
||||
|
||||
// Delete shared record
|
||||
$shared->delete();
|
||||
// Get sharing record
|
||||
Share::where('token', $token)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail()
|
||||
->delete();
|
||||
|
||||
// Get zip record
|
||||
$zip = Zip::where('shared_token', $token)
|
||||
->where('user_id', Auth::id())
|
||||
->first();
|
||||
|
||||
if ($zip) {
|
||||
$zip->delete();
|
||||
}
|
||||
}
|
||||
|
||||
// Done
|
||||
return response('Done!', 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send shared link via email to recipients
|
||||
*
|
||||
* @param $token
|
||||
* @param $request
|
||||
*/
|
||||
public function shared_send_via_email(Request $request, $token)
|
||||
{
|
||||
// Make validation of array of emails
|
||||
$validator = Validator::make($request->all(), [
|
||||
'emails.*' => 'required|email',
|
||||
]);
|
||||
|
||||
// Return error
|
||||
if ($validator->fails()) abort(400, 'Bad email input');
|
||||
|
||||
// Send shared link via email
|
||||
if($request->has('emails')) {
|
||||
foreach ($request->emails as $email) {
|
||||
Notification::route('mail', $email)->notify(new SharedSendViaEmail($token));
|
||||
}
|
||||
}
|
||||
|
||||
return response('Done!', 204);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,12 +59,12 @@ class TrashController extends Controller
|
||||
* @param $unique_id
|
||||
* @return ResponseFactory|\Illuminate\Http\Response
|
||||
*/
|
||||
public function restore(Request $request, $unique_id)
|
||||
public function restore(Request $request)
|
||||
{
|
||||
// Validate request
|
||||
$validator = Validator::make($request->all(), [
|
||||
'type' => 'required|string',
|
||||
'to_home' => 'boolean',
|
||||
$validator = Validator::make($request->input('data'), [
|
||||
'*.type' => 'required|string',
|
||||
'*.unique_id' => 'integer',
|
||||
]);
|
||||
|
||||
// Return error
|
||||
@@ -77,38 +77,41 @@ class TrashController extends Controller
|
||||
return Demo::response_204();
|
||||
}
|
||||
|
||||
// Get folder
|
||||
if ($request->type === 'folder') {
|
||||
|
||||
foreach($request->input('data') as $restore_item) {
|
||||
|
||||
// Get folder
|
||||
$item = FileManagerFolder::onlyTrashed()
|
||||
->where('user_id', $user_id)
|
||||
->where('unique_id', $unique_id)
|
||||
->first();
|
||||
if ($restore_item['type'] === 'folder') {
|
||||
|
||||
// Restore item to home directory
|
||||
if ($request->has('to_home') && $request->to_home) {
|
||||
$item->parent_id = 0;
|
||||
$item->save();
|
||||
// Get folder
|
||||
$item = FileManagerFolder::onlyTrashed()
|
||||
->where('user_id', $user_id)
|
||||
->where('unique_id', $restore_item['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', $restore_item['unique_id'])
|
||||
->first();
|
||||
|
||||
// Restore item to home directory
|
||||
if ($request->has('to_home') && $request->to_home) {
|
||||
$item->folder_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();
|
||||
}
|
||||
|
||||
// Restore Item
|
||||
$item->restore();
|
||||
|
||||
// Return response
|
||||
return response('Done!', 204);
|
||||
}
|
||||
|
||||
@@ -466,19 +466,16 @@ class SetupWizardController extends Controller
|
||||
]);
|
||||
|
||||
// Create legal pages and index content
|
||||
if ($request->license === 'Extended') {
|
||||
$pages = collect(config('content.pages'));
|
||||
$content = $request->license === 'Extended' ? collect(config('content.content_extended')) : collect(config('content.content_regular'));
|
||||
|
||||
$pages = collect(config('content.pages'));
|
||||
$content = collect(config('content.content'));
|
||||
$content->each(function ($content) {
|
||||
Setting::updateOrCreate($content);
|
||||
});
|
||||
|
||||
$content->each(function ($content) {
|
||||
Setting::updateOrCreate($content);
|
||||
});
|
||||
|
||||
$pages->each(function ($page) {
|
||||
Page::updateOrCreate($page);
|
||||
});
|
||||
}
|
||||
$pages->each(function ($page) {
|
||||
Page::updateOrCreate($page);
|
||||
});
|
||||
|
||||
// Retrieve access token
|
||||
$response = Route::dispatch(self::make_login_request($request));
|
||||
|
||||
@@ -7,120 +7,119 @@ use App\Page;
|
||||
use App\Setting;
|
||||
use Artisan;
|
||||
use Illuminate\Http\Request;
|
||||
use Schema;
|
||||
|
||||
class UpgradeAppController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Upgrade account from 1.6 to 1.7
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
|
||||
* Start maintenance mode
|
||||
*/
|
||||
public function upgrade(Request $request)
|
||||
public function up() {
|
||||
$command = Artisan::call('up');
|
||||
|
||||
if ($command === 0) {
|
||||
echo 'System is in production mode';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* End maintenance mode
|
||||
*/
|
||||
public function down() {
|
||||
$command = Artisan::call('down');
|
||||
|
||||
if ($command === 0) {
|
||||
echo 'System is in maintenance mode';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade database
|
||||
*/
|
||||
public function upgrade()
|
||||
{
|
||||
$upgraded = Setting::where('name', 'latest_upgrade')->first();
|
||||
/*
|
||||
* Upgrade user_settings & file_manager_folders table
|
||||
*
|
||||
* @since v1.8.1
|
||||
*/
|
||||
if (! Schema::hasColumn('user_settings', 'timezone') && ! Schema::hasColumn('file_manager_folders', 'icon_color')) {
|
||||
|
||||
if ($upgraded && $upgraded->value === '1.7') abort(401);
|
||||
$this->upgrade_database();
|
||||
|
||||
// Create legal pages and index content
|
||||
if ($request->license === 'Extended') {
|
||||
// Create legal pages and index content for regular license
|
||||
if (get_setting('license') === 'Regular') {
|
||||
|
||||
$pages = collect(config('content.pages'));
|
||||
$content = collect(config('content.content'));
|
||||
$pages = collect(config('content.pages'));
|
||||
$content = collect(config('content.content_regular'));
|
||||
|
||||
$content->each(function ($content) {
|
||||
Setting::updateOrCreate($content);
|
||||
});
|
||||
$content->each(function ($content) {
|
||||
Setting::updateOrCreate($content);
|
||||
});
|
||||
|
||||
$pages->each(function ($page) {
|
||||
Page::updateOrCreate($page);
|
||||
});
|
||||
$pages->each(function ($page) {
|
||||
Page::updateOrCreate($page);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Store Logo
|
||||
if ($request->hasFile('logo')) {
|
||||
$logo = store_system_image($request->file('logo'), 'system');
|
||||
/*
|
||||
* Upgrade expire_in in shares table
|
||||
*
|
||||
* @since v1.8
|
||||
*/
|
||||
if (! Schema::hasTable('traffic') && ! Schema::hasTable('zips') && ! Schema::hasTable('jobs')) {
|
||||
|
||||
$this->upgrade_database();
|
||||
}
|
||||
/*
|
||||
* Upgrade expire_in in shares table
|
||||
*
|
||||
* @since v1.8
|
||||
*/
|
||||
if (! Schema::hasTable('traffic') && ! Schema::hasTable('zips') && ! Schema::hasTable('jobs')) {
|
||||
|
||||
$this->upgrade_database();
|
||||
}
|
||||
|
||||
// Store Logo horizontal
|
||||
if ($request->hasFile('logo_horizontal')) {
|
||||
$logo_horizontal = store_system_image($request->file('logo_horizontal'), 'system');
|
||||
/*
|
||||
* Upgrade expire_in in shares table
|
||||
*
|
||||
* @since v1.7.9
|
||||
*/
|
||||
if (! Schema::hasColumn('shares', 'expire_in')) {
|
||||
|
||||
$this->upgrade_database();
|
||||
}
|
||||
|
||||
// Store favicon
|
||||
if ($request->hasFile('favicon')) {
|
||||
$favicon = store_system_image($request->file('favicon'), 'system');
|
||||
}
|
||||
/*
|
||||
* Upgrade expire_in in shares table
|
||||
*
|
||||
* @since v1.7.11
|
||||
*/
|
||||
if (! Schema::hasColumn('file_manager_files', 'metadata')) {
|
||||
|
||||
// Get options
|
||||
$settings = collect([
|
||||
[
|
||||
'name' => 'setup_wizard_database',
|
||||
'value' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'setup_wizard_success',
|
||||
'value' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'license',
|
||||
'value' => $request->license,
|
||||
],
|
||||
[
|
||||
'name' => 'purchase_code',
|
||||
'value' => $request->purchase_code,
|
||||
],
|
||||
[
|
||||
'name' => 'app_title',
|
||||
'value' => $request->title,
|
||||
],
|
||||
[
|
||||
'name' => 'app_description',
|
||||
'value' => $request->description,
|
||||
],
|
||||
[
|
||||
'name' => 'app_logo',
|
||||
'value' => $request->hasFile('logo') ? $logo : null,
|
||||
],
|
||||
[
|
||||
'name' => 'app_logo_horizontal',
|
||||
'value' => $request->hasFile('logo_horizontal') ? $logo_horizontal : null,
|
||||
],
|
||||
[
|
||||
'name' => 'app_favicon',
|
||||
'value' => $request->hasFile('favicon') ? $favicon : null,
|
||||
],
|
||||
[
|
||||
'name' => 'google_analytics',
|
||||
'value' => $request->googleAnalytics,
|
||||
],
|
||||
[
|
||||
'name' => 'contact_email',
|
||||
'value' => $request->contactMail,
|
||||
],
|
||||
[
|
||||
'name' => 'registration',
|
||||
'value' => $request->userRegistration,
|
||||
],
|
||||
[
|
||||
'name' => 'storage_limitation',
|
||||
'value' => $request->storageLimitation,
|
||||
],
|
||||
[
|
||||
'name' => 'storage_default',
|
||||
'value' => $request->defaultStorage ? $request->defaultStorage : 5,
|
||||
],
|
||||
[
|
||||
'name' => 'latest_upgrade',
|
||||
'value' => '1.7',
|
||||
],
|
||||
$this->upgrade_database();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|mixed
|
||||
*/
|
||||
private function upgrade_database()
|
||||
{
|
||||
$command = Artisan::call('migrate', [
|
||||
'--force' => true
|
||||
]);
|
||||
|
||||
// Store options
|
||||
$settings->each(function ($col) {
|
||||
Setting::updateOrCreate(['name' => $col['name']], $col);
|
||||
});
|
||||
if ($command === 0) {
|
||||
echo 'Operation was successful.';
|
||||
}
|
||||
|
||||
return response('Done', 200);
|
||||
if ($command === 1) {
|
||||
echo 'Operation failed.';
|
||||
}
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,10 @@ class FileSharingController extends Controller
|
||||
->first();
|
||||
|
||||
if ($image) {
|
||||
|
||||
// Store user download size
|
||||
User::find($shared->user_id)->record_download((int) $image->getRawOriginal('filesize'));
|
||||
|
||||
return $this->show_image($image);
|
||||
}
|
||||
}
|
||||
@@ -247,6 +251,7 @@ class FileSharingController extends Controller
|
||||
$folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
|
||||
->where('parent_id', $shared->item_id)
|
||||
->where('user_id', $shared->user_id)
|
||||
->sortable()
|
||||
->get(['id', 'parent_id', 'unique_id', 'name']);
|
||||
|
||||
// Return folder tree
|
||||
@@ -277,6 +282,7 @@ class FileSharingController extends Controller
|
||||
$folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
|
||||
->where('parent_id', $shared->item_id)
|
||||
->where('user_id', $shared->user_id)
|
||||
->sortable()
|
||||
->get(['id', 'parent_id', 'unique_id', 'name']);
|
||||
|
||||
// Return folder tree
|
||||
@@ -399,10 +405,12 @@ class FileSharingController extends Controller
|
||||
{
|
||||
$folders = FileManagerFolder::where('user_id', $shared->user_id)
|
||||
->where('parent_id', $unique_id)
|
||||
->sortable()
|
||||
->get();
|
||||
|
||||
$files = FileManagerFile::where('user_id', $shared->user_id)
|
||||
->where('folder_id', $unique_id)
|
||||
->sortable()
|
||||
->get();
|
||||
|
||||
return [$folders, $files];
|
||||
|
||||
@@ -107,7 +107,15 @@ class AccountController extends Controller
|
||||
*/
|
||||
public function update_user_settings(Request $request)
|
||||
{
|
||||
// TODO: validation
|
||||
// Validate request
|
||||
$validator = Validator::make($request->all(), [
|
||||
'name' => 'string',
|
||||
'value' => 'string',
|
||||
]);
|
||||
|
||||
// Return error
|
||||
if ($validator->fails()) abort(400, 'Bad input');
|
||||
|
||||
// Get user
|
||||
$user = Auth::user();
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
use App\FileManagerFile;
|
||||
use App\FileManagerFolder;
|
||||
use App\User;
|
||||
use App\Setting;
|
||||
use App\Share;
|
||||
use ByteUnits\Metric;
|
||||
@@ -355,6 +356,25 @@ function format_gigabytes($gigabytes)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format string to formated megabytes string
|
||||
*
|
||||
* @param $megabytes
|
||||
* @return string
|
||||
*/
|
||||
function format_megabytes($megabytes)
|
||||
{
|
||||
if ($megabytes >= 1000) {
|
||||
return $megabytes / 1000 . 'GB';
|
||||
}
|
||||
|
||||
if ($megabytes >= 1000000) {
|
||||
return $megabytes / 1000000 . 'TB';
|
||||
}
|
||||
|
||||
return $megabytes . 'MB';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert megabytes to bytes
|
||||
*
|
||||
@@ -528,4 +548,257 @@ function get_pretty_name($basename, $name, $mimetype)
|
||||
}
|
||||
|
||||
return $name . '.' . $mimetype;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get exif data from jpeg image
|
||||
*
|
||||
* @param $file
|
||||
* @return array
|
||||
*/
|
||||
function get_image_meta_data($file)
|
||||
{
|
||||
if (get_file_type_from_mimetype($file->getMimeType()) === 'jpeg') {
|
||||
|
||||
try {
|
||||
|
||||
// Try to get the exif data
|
||||
return mb_convert_encoding(Image::make($file->getRealPath())->exif(),'UTF8', 'UTF8');
|
||||
|
||||
} catch ( \Exception $e) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if app is in dev mode
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function is_dev()
|
||||
{
|
||||
return env('APP_ENV') === 'local' ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $str
|
||||
* @return bool
|
||||
*/
|
||||
function seems_utf8($str)
|
||||
{
|
||||
$length = strlen($str);
|
||||
for ($i=0; $i < $length; $i++) {
|
||||
$c = ord($str[$i]);
|
||||
if ($c < 0x80) $n = 0; # 0bbbbbbb
|
||||
elseif (($c & 0xE0) == 0xC0) $n=1; # 110bbbbb
|
||||
elseif (($c & 0xF0) == 0xE0) $n=2; # 1110bbbb
|
||||
elseif (($c & 0xF8) == 0xF0) $n=3; # 11110bbb
|
||||
elseif (($c & 0xFC) == 0xF8) $n=4; # 111110bb
|
||||
elseif (($c & 0xFE) == 0xFC) $n=5; # 1111110b
|
||||
else return false; # Does not match any model
|
||||
for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
|
||||
if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts all accent characters to ASCII characters.
|
||||
*
|
||||
* If there are no accent characters, then the string given is just returned.
|
||||
*
|
||||
* @param string $string Text that might have accent characters
|
||||
* @return string Filtered string with replaced "nice" characters.
|
||||
*/
|
||||
function remove_accents($string) {
|
||||
if ( !preg_match('/[\x80-\xff]/', $string) )
|
||||
return $string;
|
||||
|
||||
if (seems_utf8($string)) {
|
||||
$chars = array(
|
||||
// Decompositions for Latin-1 Supplement
|
||||
chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
|
||||
chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
|
||||
chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
|
||||
chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
|
||||
chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
|
||||
chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
|
||||
chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
|
||||
chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
|
||||
chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
|
||||
chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
|
||||
chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
|
||||
chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
|
||||
chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
|
||||
chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
|
||||
chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
|
||||
chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
|
||||
chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
|
||||
chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
|
||||
chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
|
||||
chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
|
||||
chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
|
||||
chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
|
||||
chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
|
||||
chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
|
||||
chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
|
||||
chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
|
||||
chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
|
||||
chr(195).chr(191) => 'y',
|
||||
// Decompositions for Latin Extended-A
|
||||
chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
|
||||
chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
|
||||
chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
|
||||
chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
|
||||
chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
|
||||
chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
|
||||
chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
|
||||
chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
|
||||
chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
|
||||
chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
|
||||
chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
|
||||
chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
|
||||
chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
|
||||
chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
|
||||
chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
|
||||
chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
|
||||
chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
|
||||
chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
|
||||
chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
|
||||
chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
|
||||
chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
|
||||
chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
|
||||
chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
|
||||
chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
|
||||
chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
|
||||
chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
|
||||
chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
|
||||
chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
|
||||
chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
|
||||
chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
|
||||
chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
|
||||
chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
|
||||
chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
|
||||
chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
|
||||
chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
|
||||
chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
|
||||
chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
|
||||
chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
|
||||
chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
|
||||
chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
|
||||
chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
|
||||
chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
|
||||
chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
|
||||
chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
|
||||
chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
|
||||
chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
|
||||
chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
|
||||
chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
|
||||
chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
|
||||
chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
|
||||
chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
|
||||
chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
|
||||
chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
|
||||
chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
|
||||
chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
|
||||
chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
|
||||
chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
|
||||
chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
|
||||
chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
|
||||
chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
|
||||
chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
|
||||
chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
|
||||
chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
|
||||
chr(197).chr(190) => 'z', chr(197).chr(191) => 's',
|
||||
// Euro Sign
|
||||
chr(226).chr(130).chr(172) => 'E',
|
||||
// GBP (Pound) Sign
|
||||
chr(194).chr(163) => '');
|
||||
|
||||
$string = strtr($string, $chars);
|
||||
} else {
|
||||
// Assume ISO-8859-1 if not UTF-8
|
||||
$chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158)
|
||||
.chr(159).chr(162).chr(165).chr(181).chr(192).chr(193).chr(194)
|
||||
.chr(195).chr(196).chr(197).chr(199).chr(200).chr(201).chr(202)
|
||||
.chr(203).chr(204).chr(205).chr(206).chr(207).chr(209).chr(210)
|
||||
.chr(211).chr(212).chr(213).chr(214).chr(216).chr(217).chr(218)
|
||||
.chr(219).chr(220).chr(221).chr(224).chr(225).chr(226).chr(227)
|
||||
.chr(228).chr(229).chr(231).chr(232).chr(233).chr(234).chr(235)
|
||||
.chr(236).chr(237).chr(238).chr(239).chr(241).chr(242).chr(243)
|
||||
.chr(244).chr(245).chr(246).chr(248).chr(249).chr(250).chr(251)
|
||||
.chr(252).chr(253).chr(255);
|
||||
|
||||
$chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy";
|
||||
|
||||
$string = strtr($string, $chars['in'], $chars['out']);
|
||||
$double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254));
|
||||
$double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th');
|
||||
$string = str_replace($double_chars['in'], $double_chars['out'], $string);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
/**
|
||||
* Get all files from folder and get their folder location in VueFileManager directories
|
||||
*
|
||||
* @param $folders
|
||||
* @param null $files
|
||||
* @param array $path
|
||||
* @return array
|
||||
*/
|
||||
function get_files_for_zip($folders, $files, $path = [])
|
||||
{
|
||||
// Return file list
|
||||
if (!isset($folders->folders)) {
|
||||
return $files->unique()->values()->all();
|
||||
}
|
||||
|
||||
// Push file path
|
||||
array_push($path, $folders->name);
|
||||
|
||||
// Push file to collection
|
||||
$folders->files->each(function ($file) use ($files, $path) {
|
||||
$files->push([
|
||||
'name' => $file->name,
|
||||
'basename' => $file->basename,
|
||||
'folder_path' => implode('/', $path),
|
||||
]);
|
||||
});
|
||||
|
||||
// Get all children folders and folders within
|
||||
if ($folders->folders->isNotEmpty()) {
|
||||
$folders->folders->map(function ($folder) use ($files, $path) {
|
||||
return get_files_for_zip($folder, $files, $path);
|
||||
});
|
||||
}
|
||||
|
||||
return get_files_for_zip($folders->folders->first(), $files, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set time by user timezone GMT
|
||||
*
|
||||
* @param $time
|
||||
* @return int
|
||||
*/
|
||||
function set_time_by_user_timezone($time)
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
if($user) {
|
||||
|
||||
// Get the value of timezone if user have some
|
||||
$time_zone = intval($user->settings->timezone * 60 ?? null);
|
||||
|
||||
return Carbon::parse($time)->addMinutes($time_zone ?? null);
|
||||
}
|
||||
|
||||
return Carbon::parse($time);
|
||||
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ class CheckForMaintenanceMode extends Middleware
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
'/service/upgrade-database',
|
||||
'/service/down',
|
||||
'/service/up',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -25,8 +25,9 @@ class DeleteItemRequest extends FormRequest
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'data.type' => 'required|string',
|
||||
'data.force_delete' => 'required|boolean',
|
||||
'data[*].force_delete' => 'required|boolean',
|
||||
'data[*].type' => 'required|string',
|
||||
'data[*].unique_id' => 'required|integer'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,9 @@ class MoveItemRequest extends FormRequest
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'to_unique_id' => 'required|integer',
|
||||
'from_type' => 'required|string',
|
||||
'to_unique_id' => 'required|integer',
|
||||
'items[*].type' => 'required|string',
|
||||
'items[*].unique_id' => 'required|integer',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Requests\FileFunctions;
|
||||
|
||||
use App\Rules\MimetypeBlacklistValidation;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
@@ -26,7 +27,7 @@ class UploadRequest extends FormRequest
|
||||
{
|
||||
return [
|
||||
'parent_id' => 'required|integer',
|
||||
'file' => 'required|file',
|
||||
'file' => ['required','file' , new MimetypeBlacklistValidation]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,10 @@ class CreateShareRequest extends FormRequest
|
||||
'isPassword' => 'required|boolean',
|
||||
'unique_id' => 'required|integer',
|
||||
'type' => 'required|string',
|
||||
'expiration' => 'integer|nullable',
|
||||
'permission' => 'string',
|
||||
'password' => 'string',
|
||||
'emails.*' => 'email'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ class UpdateShareRequest extends FormRequest
|
||||
return [
|
||||
'protected' => 'required|boolean',
|
||||
'permission' => 'nullable|string',
|
||||
'expiration' => 'integer|nullable',
|
||||
'password' => 'string',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class StoreUpgradeAccountRequest extends FormRequest
|
||||
'plan.data.attributes.capacity' => 'required|digits_between:1,9',
|
||||
'plan.data.attributes.capacity_formatted' => 'required|string',
|
||||
'plan.data.attributes.currency' => 'required|string',
|
||||
'plan.data.attributes.description' => 'required|string',
|
||||
'plan.data.attributes.description' => 'sometimes|string|nullable',
|
||||
'plan.data.attributes.name' => 'required|string',
|
||||
'plan.data.attributes.price' => 'required|string',
|
||||
'plan.data.id' => 'required|string',
|
||||
|
||||
@@ -22,6 +22,7 @@ class ShareResource extends JsonResource
|
||||
'permission' => $this->permission,
|
||||
'protected' => (int) $this->protected,
|
||||
'item_id' => (int) $this->item_id,
|
||||
'expire_in' => (int) $this->expire_in,
|
||||
'token' => $this->token,
|
||||
'link' => $this->link,
|
||||
'type' => $this->type,
|
||||
|
||||
@@ -76,7 +76,16 @@ class UserResource extends JsonResource
|
||||
'folders' => $this->folder_tree
|
||||
],
|
||||
],
|
||||
]
|
||||
],
|
||||
'timezone' => [
|
||||
'data' => [
|
||||
'id' => '1',
|
||||
'type' => 'timezone',
|
||||
'attributes' => [
|
||||
'timezone' =>$this->settings->timezone
|
||||
],
|
||||
]
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
@@ -72,15 +72,17 @@ class Demo
|
||||
|
||||
if ($item) {
|
||||
$item->name = $request->name;
|
||||
$item->icon_emoji = $request->folder_icon['emoji'] ?? null;
|
||||
$item->icon_color = $request->folder_icon['color'] ?? null;
|
||||
|
||||
return $item;
|
||||
|
||||
} else {
|
||||
|
||||
return [
|
||||
'unique_id' => $request->unique_id,
|
||||
'name' => $request->name,
|
||||
'type' => $request->type,
|
||||
'unique_id' => $request->unique_id,
|
||||
'name' => $request->name,
|
||||
'type' => $request->type,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -126,7 +128,8 @@ class Demo
|
||||
*
|
||||
* @return ResponseFactory|\Illuminate\Http\Response
|
||||
*/
|
||||
public static function response_204() {
|
||||
public static function response_204()
|
||||
{
|
||||
|
||||
return response('Done!', 204);
|
||||
}
|
||||
@@ -136,7 +139,8 @@ class Demo
|
||||
*
|
||||
* @return ResponseFactory|\Illuminate\Http\Response
|
||||
*/
|
||||
public static function favourites($user) {
|
||||
public static function favourites($user)
|
||||
{
|
||||
|
||||
return $user->favourite_folders->makeHidden(['pivot']);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\FileManagerFile;
|
||||
use App\FileManagerFolder;
|
||||
use App\Http\Requests\FileFunctions\RenameItemRequest;
|
||||
use App\User;
|
||||
use App\Zip;
|
||||
use Aws\Exception\MultipartUploadException;
|
||||
use Aws\S3\MultipartUploader;
|
||||
use Carbon\Carbon;
|
||||
@@ -18,11 +19,199 @@ use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use Intervention\Image\ImageManagerStatic as Image;
|
||||
use League\Flysystem\FileNotFoundException;
|
||||
use Madnest\Madzipper\Facades\Madzipper;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
|
||||
class Editor
|
||||
{
|
||||
/**
|
||||
* Store folder icon
|
||||
*
|
||||
* @param $folder_icon
|
||||
* @param $unique_id
|
||||
* @param $shared
|
||||
*/
|
||||
public static function set_folder_icon($folder_icon, $unique_id, $shared = null)
|
||||
{
|
||||
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
|
||||
|
||||
// Get folder
|
||||
$folder = FileManagerFolder::where('user_id', $user_id)
|
||||
->where('unique_id', $unique_id)
|
||||
->first();
|
||||
|
||||
// Set default folder icon
|
||||
if ($folder_icon === 'default') {
|
||||
$folder->icon_emoji = null;
|
||||
$folder->icon_color = null;
|
||||
}
|
||||
|
||||
// If request have emoji set folder icon emoji
|
||||
if (isset($folder_icon['emoji'])) {
|
||||
$folder->icon_emoji = $folder_icon['emoji'];
|
||||
$folder->icon_color = null;
|
||||
}
|
||||
|
||||
// If request have color set folder icon color
|
||||
if (isset($folder_icon['color'])) {
|
||||
$folder->icon_emoji = null;
|
||||
$folder->icon_color = $folder_icon['color'];
|
||||
}
|
||||
|
||||
// Save changes
|
||||
$folder->save();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zip requested folder
|
||||
*
|
||||
* @param $unique_id
|
||||
* @param $shared
|
||||
* @return mixed
|
||||
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
|
||||
*/
|
||||
public static function zip_folder($unique_id, $shared = null)
|
||||
{
|
||||
// Get folder
|
||||
$requested_folder = FileManagerFolder::with(['folders.files', 'files'])
|
||||
->where('unique_id', $unique_id)
|
||||
->where('user_id', Auth::id() ?? $shared->user_id)
|
||||
->with('folders')
|
||||
->first();
|
||||
|
||||
$files = get_files_for_zip($requested_folder, collect([]));
|
||||
|
||||
// Local storage instance
|
||||
$disk_local = Storage::disk('local');
|
||||
|
||||
// Create zip directory
|
||||
if (!$disk_local->exists('zip')) {
|
||||
$disk_local->makeDirectory('zip');
|
||||
}
|
||||
|
||||
// Move file to local storage
|
||||
if (!is_storage_driver('local')) {
|
||||
|
||||
// Create temp directory
|
||||
if (!$disk_local->exists('temp')) {
|
||||
$disk_local->makeDirectory('temp');
|
||||
}
|
||||
|
||||
foreach ($files as $file) {
|
||||
try {
|
||||
$disk_local->put('temp/' . $file['basename'], Storage::get('file-manager/' . $file['basename']));
|
||||
} catch (FileNotFoundException $e) {
|
||||
throw new HttpException(404, 'File not found');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get zip path
|
||||
$zip_name = Str::random(16) . '-' . Str::slug($requested_folder->name) . '.zip';
|
||||
$zip_path = 'zip/' . $zip_name;
|
||||
|
||||
// Create zip
|
||||
$zip = Madzipper::make(storage_path() . '/app/' . $zip_path);
|
||||
|
||||
// Get files folder on local storage drive
|
||||
$files_folder = is_storage_driver('local') ? 'file-manager' : 'temp';
|
||||
|
||||
// Add files to zip
|
||||
foreach ($files as $file) {
|
||||
$zip->folder($file['folder_path'])->addString($file['name'], File::get(storage_path() . '/app/' . $files_folder . '/' . $file['basename']));
|
||||
}
|
||||
|
||||
// Close zip
|
||||
$zip->close();
|
||||
|
||||
// Delete temporary files
|
||||
if (!is_storage_driver('local')) {
|
||||
|
||||
foreach ($files as $file) {
|
||||
$disk_local->delete('temp/' . $file['basename']);
|
||||
}
|
||||
}
|
||||
|
||||
// Store zip record
|
||||
return Zip::create([
|
||||
'user_id' => $shared->user_id ?? Auth::id(),
|
||||
'shared_token' => $shared->token ?? null,
|
||||
'basename' => $zip_name,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zip selected files, store it in /zip folder and retrieve zip record
|
||||
*
|
||||
* @param $files
|
||||
* @param null $shared
|
||||
* @return mixed
|
||||
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
|
||||
*/
|
||||
public static function zip_files($files, $shared = null)
|
||||
{
|
||||
// Local storage instance
|
||||
$disk_local = Storage::disk('local');
|
||||
|
||||
// Create zip directory
|
||||
if (!$disk_local->exists('zip')) {
|
||||
$disk_local->makeDirectory('zip');
|
||||
}
|
||||
|
||||
// Move file to local storage from external storage service
|
||||
if (!is_storage_driver('local')) {
|
||||
|
||||
// Create temp directory
|
||||
if (!$disk_local->exists('temp')) {
|
||||
$disk_local->makeDirectory('temp');
|
||||
}
|
||||
|
||||
foreach ($files as $file) {
|
||||
try {
|
||||
$disk_local->put('temp/' . $file['basename'], Storage::get('file-manager/' . $file['basename']));
|
||||
} catch (FileNotFoundException $e) {
|
||||
throw new HttpException(404, 'File not found');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get zip path
|
||||
$zip_name = Str::random(16) . '.zip';
|
||||
$zip_path = 'zip/' . $zip_name;
|
||||
|
||||
// Create zip
|
||||
$zip = Madzipper::make(storage_path() . '/app/' . $zip_path);
|
||||
|
||||
// Get files folder on local storage drive
|
||||
$files_directory = is_storage_driver('local') ? 'file-manager' : 'temp';
|
||||
|
||||
// Add files to zip
|
||||
$files->each(function ($file) use ($zip, $files_directory) {
|
||||
$zip->addString($file['name'] . '.' . $file['mimetype'], File::get(storage_path() . '/app/' . $files_directory . '/' . $file['basename']));
|
||||
});
|
||||
|
||||
// Close zip
|
||||
$zip->close();
|
||||
|
||||
// Delete temporary files
|
||||
if (!is_storage_driver('local')) {
|
||||
|
||||
$files->each(function ($file) use ($disk_local) {
|
||||
$disk_local->delete('temp/' . $file['basename']);
|
||||
});
|
||||
}
|
||||
|
||||
// Store zip record
|
||||
return Zip::create([
|
||||
'user_id' => $shared->user_id ?? Auth::id(),
|
||||
'shared_token' => $shared->token ?? null,
|
||||
'basename' => $zip_name,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new directory
|
||||
*
|
||||
@@ -86,13 +275,13 @@ class Editor
|
||||
* @param null $shared
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function delete_item($request, $unique_id, $shared = null)
|
||||
public static function delete_item($file, $unique_id, $shared = null)
|
||||
{
|
||||
// Get user id
|
||||
$user = is_null($shared) ? Auth::user() : User::findOrFail($shared->user_id);
|
||||
|
||||
// Delete folder
|
||||
if ($request->input('data.type') === 'folder') {
|
||||
if ($file['type'] === 'folder') {
|
||||
|
||||
// Get folder
|
||||
$folder = FileManagerFolder::withTrashed()
|
||||
@@ -113,7 +302,7 @@ class Editor
|
||||
}
|
||||
|
||||
// Force delete children files
|
||||
if ($request->input('data.force_delete')) {
|
||||
if ($file['force_delete']) {
|
||||
|
||||
// Get children folder ids
|
||||
$child_folders = filter_folders_ids($folder->trashed_folders, 'unique_id');
|
||||
@@ -142,7 +331,7 @@ class Editor
|
||||
}
|
||||
|
||||
// Soft delete items
|
||||
if (!$request->input('data.force_delete')) {
|
||||
if (!$file['force_delete']) {
|
||||
|
||||
// Remove folder from user favourites
|
||||
$user->favourite_folders()->detach($unique_id);
|
||||
@@ -153,10 +342,10 @@ class Editor
|
||||
}
|
||||
|
||||
// Delete item
|
||||
if ($request->input('data.type') !== 'folder') {
|
||||
if ($file['type'] !== 'folder') {
|
||||
|
||||
// Get file
|
||||
$file = FileManagerFile::withTrashed()
|
||||
$item = FileManagerFile::withTrashed()
|
||||
->where('user_id', $user->id)
|
||||
->where('unique_id', $unique_id)
|
||||
->first();
|
||||
@@ -173,23 +362,23 @@ class Editor
|
||||
}
|
||||
|
||||
// Force delete file
|
||||
if ($request->input('data.force_delete')) {
|
||||
if ($file['force_delete']) {
|
||||
|
||||
// Delete file
|
||||
Storage::delete('/file-manager/' . $file->basename);
|
||||
Storage::delete('/file-manager/' . $item->basename);
|
||||
|
||||
// Delete thumbnail if exist
|
||||
if ($file->thumbnail) Storage::delete('/file-manager/' . $file->getRawOriginal('thumbnail'));
|
||||
if ($item->thumbnail) Storage::delete('/file-manager/' . $item->getRawOriginal('thumbnail'));
|
||||
|
||||
// Delete file permanently
|
||||
$file->forceDelete();
|
||||
$item->forceDelete();
|
||||
}
|
||||
|
||||
// Soft delete file
|
||||
if (!$request->input('data.force_delete')) {
|
||||
if (!$file['force_delete']) {
|
||||
|
||||
// Soft delete file
|
||||
$file->delete();
|
||||
$item->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,32 +390,36 @@ class Editor
|
||||
* @param $unique_id
|
||||
* @param null $shared
|
||||
*/
|
||||
public static function move($request, $unique_id, $shared = null)
|
||||
public static function move($request, $to_unique_id, $shared = null)
|
||||
{
|
||||
// Get user id
|
||||
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
|
||||
|
||||
if ($request->from_type === 'folder') {
|
||||
foreach ($request->input('items') as $item) {
|
||||
$unique_id = $item['unique_id'];
|
||||
|
||||
// Move folder
|
||||
$item = FileManagerFolder::where('user_id', $user_id)
|
||||
->where('unique_id', $unique_id)
|
||||
->firstOrFail();
|
||||
if ($item['type'] === 'folder') {
|
||||
|
||||
$item->update([
|
||||
'parent_id' => $request->to_unique_id
|
||||
]);
|
||||
// Move folder
|
||||
$item = FileManagerFolder::where('user_id', $user_id)
|
||||
->where('unique_id', $unique_id)
|
||||
->firstOrFail();
|
||||
|
||||
} else {
|
||||
$item->update([
|
||||
'parent_id' => $to_unique_id
|
||||
]);
|
||||
|
||||
// Move file under new folder
|
||||
$item = FileManagerFile::where('user_id', $user_id)
|
||||
->where('unique_id', $unique_id)
|
||||
->firstOrFail();
|
||||
} else {
|
||||
|
||||
$item->update([
|
||||
'folder_id' => $request->to_unique_id
|
||||
]);
|
||||
// Move file under new folder
|
||||
$item = FileManagerFile::where('user_id', $user_id)
|
||||
->where('unique_id', $unique_id)
|
||||
->firstOrFail();
|
||||
|
||||
$item->update([
|
||||
'folder_id' => $to_unique_id
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,12 +444,26 @@ class Editor
|
||||
$disk_file_name = basename('chunks/' . $file->getClientOriginalName(), '.part');
|
||||
$temp_filename = $file->getClientOriginalName();
|
||||
|
||||
// File Path
|
||||
$file_path = config('filesystems.disks.local.root') . '/chunks/' . $temp_filename;
|
||||
|
||||
// Generate file
|
||||
File::append(config('filesystems.disks.local.root') . '/chunks/' . $temp_filename, $file->get());
|
||||
File::append($file_path, $file->get());
|
||||
|
||||
// Size of file
|
||||
$file_size = File::size($file_path);
|
||||
|
||||
// Size of limit
|
||||
$limit = get_setting('upload_limit');
|
||||
|
||||
// File size handling
|
||||
if ($limit && $file_size > format_bytes($limit)) abort(413);
|
||||
|
||||
// If last then process file
|
||||
if ($request->boolean('is_last')) {
|
||||
|
||||
$metadata = get_image_meta_data($file);
|
||||
|
||||
$disk_local = Storage::disk('local');
|
||||
$unique_id = get_unique_id();
|
||||
|
||||
@@ -292,6 +499,7 @@ class Editor
|
||||
'mimetype' => get_file_type_from_mimetype($file_mimetype),
|
||||
'type' => get_file_type($file_mimetype),
|
||||
'folder_id' => $request->parent_id,
|
||||
'metadata' => $metadata,
|
||||
'name' => $user_file_name,
|
||||
'unique_id' => $unique_id,
|
||||
'basename' => $disk_file_name,
|
||||
@@ -301,6 +509,19 @@ class Editor
|
||||
'user_id' => $user_id,
|
||||
];
|
||||
|
||||
// Store user upload size
|
||||
if ($request->user()) {
|
||||
|
||||
// If upload a loged user
|
||||
$request->user()->record_upload($file_size);
|
||||
|
||||
} else {
|
||||
|
||||
// If upload guest
|
||||
User::find($shared->user_id)->record_upload($file_size);
|
||||
|
||||
}
|
||||
|
||||
// Return new file
|
||||
return FileManagerFile::create($options);
|
||||
}
|
||||
|
||||
64
app/Notifications/SharedSendViaEmail.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
|
||||
class SharedSendViaEmail extends Notification
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @param $token
|
||||
*/
|
||||
public function __construct($token)
|
||||
{
|
||||
$this->token = $token;
|
||||
$this->user = Auth::user();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ['mail'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
return (new MailMessage)
|
||||
->subject(__('vuefilemanager.shared_link_email_subject' , ['user' => $this->user->name]))
|
||||
->greeting(__('vuefilemanager.shared_link_email_greeting'))
|
||||
->line(__('vuefilemanager.shared_link_email_user', ['user' => $this->user->name, 'email' => $this->user->email]))
|
||||
->action(__('vuefilemanager.shared_link_email_link'), url('/shared', ['token' => $this->token]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
||||
19
app/Page.php
@@ -5,6 +5,25 @@ namespace App;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Kyslik\ColumnSortable\Sortable;
|
||||
|
||||
/**
|
||||
* App\Page
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $visibility
|
||||
* @property string $title
|
||||
* @property string $slug
|
||||
* @property string $content
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Page newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Page newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Page query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Page sortable($defaultParameters = null)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Page whereContent($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Page whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Page whereSlug($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Page whereTitle($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Page whereVisibility($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class Page extends Model
|
||||
{
|
||||
use Sortable;
|
||||
|
||||
42
app/Rules/MimetypeBlacklistValidation.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Rules;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
|
||||
class MimetypeBlacklistValidation implements Rule
|
||||
{
|
||||
/**
|
||||
* Create a new rule instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the validation rule passes.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
$mimetype_blacklist = explode(',' ,get_setting('mimetypes_blacklist'));
|
||||
$file_mimetype = explode('/' ,$value->getMimeType());
|
||||
|
||||
return !array_intersect($file_mimetype , $mimetype_blacklist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
abort (415,'Type of this mime type is not allowed.');
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,20 @@ namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* App\Setting
|
||||
*
|
||||
* @property int $id
|
||||
* @property string $name
|
||||
* @property string|null $value
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Setting newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Setting newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Setting query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Setting whereValue($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class Setting extends Model
|
||||
{
|
||||
public $timestamps = false;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Notifications\SharedSendViaEmail;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
/**
|
||||
* App\Share
|
||||
@@ -32,9 +34,13 @@ use Illuminate\Database\Eloquent\Model;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\Share whereUserId($value)
|
||||
* @mixin \Eloquent
|
||||
* @property int|null $expire_in
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Share whereExpireIn($value)
|
||||
*/
|
||||
class Share extends Model
|
||||
{
|
||||
use Notifiable;
|
||||
|
||||
protected $guarded = ['id'];
|
||||
|
||||
protected $appends = ['link'];
|
||||
@@ -44,8 +50,8 @@ class Share extends Model
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLinkAttribute() {
|
||||
|
||||
public function getLinkAttribute()
|
||||
{
|
||||
return url('/shared', ['token' => $this->attributes['token']]);
|
||||
}
|
||||
}
|
||||
|
||||
30
app/Traffic.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* App\Traffic
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $user_id
|
||||
* @property int $upload
|
||||
* @property int $download
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Traffic newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Traffic newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Traffic query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Traffic whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Traffic whereDownload($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Traffic whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Traffic whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Traffic whereUpload($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Traffic whereUserId($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class Traffic extends Model
|
||||
{
|
||||
protected $fillable = ['user_id', 'upload', 'download'];
|
||||
}
|
||||
55
app/User.php
@@ -5,6 +5,7 @@ namespace App;
|
||||
use App\Notifications\ResetPassword;
|
||||
use App\Notifications\ResetUserPasswordNotification;
|
||||
use ByteUnits\Metric;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
@@ -73,6 +74,7 @@ use Rinvex\Subscriptions\Traits\HasSubscriptions;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereRole($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereStripeId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|\App\User whereTrialEndsAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User sortable($defaultParameters = null)
|
||||
*/
|
||||
class User extends Authenticatable
|
||||
{
|
||||
@@ -156,10 +158,10 @@ class User extends Authenticatable
|
||||
$is_storage_limit = $storage_limitation ? $storage_limitation : 1;
|
||||
|
||||
// Get user storage usage
|
||||
if (! $is_storage_limit) {
|
||||
if (!$is_storage_limit) {
|
||||
|
||||
return [
|
||||
'used' => $this->used_capacity,
|
||||
'used' => $this->used_capacity,
|
||||
'used_formatted' => Metric::bytes($this->used_capacity)->format(),
|
||||
];
|
||||
}
|
||||
@@ -193,9 +195,12 @@ class User extends Authenticatable
|
||||
*/
|
||||
public function getFolderTreeAttribute()
|
||||
{
|
||||
return FileManagerFolder::with(['folders.shared', 'shared:token,id,item_id,permission,protected'])
|
||||
// Get sorting setup
|
||||
|
||||
return FileManagerFolder::with(['folders.shared', 'shared:token,id,item_id,permission,protected,expire_in'])
|
||||
->where('parent_id', 0)
|
||||
->where('user_id', $this->id)
|
||||
->sortable()
|
||||
->get();
|
||||
}
|
||||
|
||||
@@ -251,6 +256,46 @@ class User extends Authenticatable
|
||||
$this->notify(new ResetPassword($token));
|
||||
}
|
||||
|
||||
/**
|
||||
* Record user upload filesize
|
||||
*
|
||||
* @param $file_size
|
||||
*/
|
||||
public function record_upload($file_size)
|
||||
{
|
||||
$now = Carbon::now();
|
||||
|
||||
$record = Traffic::whereYear('created_at', '=', $now->year)
|
||||
->whereMonth('created_at', '=', $now->month)
|
||||
->firstOrCreate([
|
||||
'user_id' => $this->id,
|
||||
]);
|
||||
|
||||
$record->update([
|
||||
'upload' => $record->upload + $file_size
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Record user download filesize
|
||||
*
|
||||
* @param $file_size
|
||||
*/
|
||||
public function record_download($file_size)
|
||||
{
|
||||
$now = Carbon::now();
|
||||
|
||||
$record = Traffic::whereYear('created_at', '=', $now->year)
|
||||
->whereMonth('created_at', '=', $now->month)
|
||||
->firstOrCreate([
|
||||
'user_id' => $this->id,
|
||||
]);
|
||||
|
||||
$record->update([
|
||||
'download' => $record->download + $file_size
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user favourites folder
|
||||
*
|
||||
@@ -258,7 +303,7 @@ class User extends Authenticatable
|
||||
*/
|
||||
public function favourite_folders()
|
||||
{
|
||||
return $this->belongsToMany(FileManagerFolder::class, 'favourite_folder', 'user_id', 'folder_unique_id', 'id', 'unique_id')->with('shared:token,id,item_id,permission,protected');
|
||||
return $this->belongsToMany(FileManagerFolder::class, 'favourite_folder', 'user_id', 'folder_unique_id', 'id', 'unique_id')->with('shared:token,id,item_id,permission,protected,expire_in');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -268,7 +313,7 @@ class User extends Authenticatable
|
||||
*/
|
||||
public function latest_uploads()
|
||||
{
|
||||
return $this->hasMany(FileManagerFile::class)->with(['parent'])->orderBy('created_at', 'DESC')->take(40);
|
||||
return $this->hasMany(FileManagerFile::class)->with(['parent'])->take(40);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,34 @@ namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* App\UserSettings
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $user_id
|
||||
* @property int $storage_capacity
|
||||
* @property string|null $billing_name
|
||||
* @property string|null $billing_address
|
||||
* @property string|null $billing_state
|
||||
* @property string|null $billing_city
|
||||
* @property string|null $billing_postal_code
|
||||
* @property string|null $billing_country
|
||||
* @property string|null $billing_phone_number
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingAddress($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingCity($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingCountry($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingName($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingPhoneNumber($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingPostalCode($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereBillingState($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereStorageCapacity($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|UserSettings whereUserId($value)
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class UserSettings extends Model
|
||||
{
|
||||
public $timestamps = false;
|
||||
|
||||
27
app/Zip.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Zip extends Model
|
||||
{
|
||||
protected $guarded = ['id'];
|
||||
|
||||
public $incrementing = false;
|
||||
|
||||
protected $keyType = 'string';
|
||||
|
||||
/**
|
||||
* Generate uuid
|
||||
*/
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::creating(function ($model) {
|
||||
$model->id = (string)Str::uuid();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
"fruitcake/laravel-cors": "^1.0",
|
||||
"gabrielelana/byte-units": "^0.5.0",
|
||||
"intervention/image": "^2.5",
|
||||
"jaybizzle/laravel-crawler-detect": "^1.2",
|
||||
"kyslik/column-sortable": "^6.3",
|
||||
"laravel/cashier": "^12.0",
|
||||
"laravel/framework": "^7.0",
|
||||
@@ -24,6 +25,7 @@
|
||||
"laravel/ui": "^2.0",
|
||||
"league/flysystem-aws-s3-v3": "^1.0",
|
||||
"league/flysystem-cached-adapter": "^1.0",
|
||||
"madnest/madzipper": "^1.1",
|
||||
"teamtnt/laravel-scout-tntsearch-driver": "^8.3"
|
||||
},
|
||||
"require-dev": {
|
||||
|
||||
172
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "0d1b10acc2a996969b828cc7f51cdee6",
|
||||
"content-hash": "2753a719196cd76d1bd7ee346540266c",
|
||||
"packages": [
|
||||
{
|
||||
"name": "asm89/stack-cors",
|
||||
@@ -1467,6 +1467,119 @@
|
||||
],
|
||||
"time": "2019-11-02T09:15:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jaybizzle/crawler-detect",
|
||||
"version": "v1.2.98",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/JayBizzle/Crawler-Detect.git",
|
||||
"reference": "02b24e5d4dc347737577f48c688ee14c3b5dfd4f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/02b24e5d4dc347737577f48c688ee14c3b5dfd4f",
|
||||
"reference": "02b24e5d4dc347737577f48c688ee14c3b5dfd4f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8|^5.5|^6.5",
|
||||
"satooshi/php-coveralls": "1.*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Jaybizzle\\CrawlerDetect\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Beech",
|
||||
"email": "m@rkbee.ch",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "CrawlerDetect is a PHP class for detecting bots/crawlers/spiders via the user agent",
|
||||
"homepage": "https://github.com/JayBizzle/Crawler-Detect/",
|
||||
"keywords": [
|
||||
"crawler",
|
||||
"crawler detect",
|
||||
"crawler detector",
|
||||
"crawlerdetect",
|
||||
"php crawler detect"
|
||||
],
|
||||
"time": "2020-08-20T18:36:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jaybizzle/laravel-crawler-detect",
|
||||
"version": "v1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/JayBizzle/Laravel-Crawler-Detect.git",
|
||||
"reference": "e39b536fb5e4f21a49328e83a2ab26f0b64b06f7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/JayBizzle/Laravel-Crawler-Detect/zipball/e39b536fb5e4f21a49328e83a2ab26f0b64b06f7",
|
||||
"reference": "e39b536fb5e4f21a49328e83a2ab26f0b64b06f7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"jaybizzle/crawler-detect": "1.*",
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"orchestra/testbench": "3.1.*",
|
||||
"phpunit/phpunit": "4.*"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Jaybizzle\\LaravelCrawlerDetect\\LaravelCrawlerDetectServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"Crawler": "Jaybizzle\\LaravelCrawlerDetect\\Facades\\LaravelCrawlerDetect"
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Jaybizzle\\LaravelCrawlerDetect\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Beech",
|
||||
"email": "mbeech@mark-beech.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "A Laravel package to detect web crawlers via the user agent",
|
||||
"homepage": "http://github.com/JayBizzle/Laravel-Crawler-Detect",
|
||||
"keywords": [
|
||||
"bot",
|
||||
"crawler",
|
||||
"crawler detect",
|
||||
"crawler detector",
|
||||
"crawlerdetect",
|
||||
"detect",
|
||||
"laravel",
|
||||
"php crawler detect",
|
||||
"spider",
|
||||
"user-agent"
|
||||
],
|
||||
"time": "2017-06-01T20:29:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "kyslik/column-sortable",
|
||||
"version": "6.3.0",
|
||||
@@ -2665,6 +2778,62 @@
|
||||
],
|
||||
"time": "2020-07-01T11:33:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "madnest/madzipper",
|
||||
"version": "v1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/madnest/madzipper.git",
|
||||
"reference": "fd1d8199d04eac103eed9355c9bba680dcf8b89b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/madnest/madzipper/zipball/fd1d8199d04eac103eed9355c9bba680dcf8b89b",
|
||||
"reference": "fd1d8199d04eac103eed9355c9bba680dcf8b89b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-zip": "*",
|
||||
"illuminate/filesystem": "^6.18|^7.0|^8.0",
|
||||
"illuminate/support": "^6.18|^7.0|^8.0",
|
||||
"php": ">=7.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.3",
|
||||
"orchestra/testbench": "^5.1",
|
||||
"phpunit/phpunit": "^8.0|^9.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Madnest\\Madzipper\\MadzipperServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"Madzipper": "Madnest\\Madzipper\\Madzipper"
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Madnest\\Madzipper\\": "src/Madnest/Madzipper"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jakub Theimer",
|
||||
"email": "theimer@madne.st",
|
||||
"homepage": "https://madne.st",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Wannabe successor of Chumper/Zipper package for Laravel",
|
||||
"time": "2020-12-01T23:44:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "moneyphp/money",
|
||||
"version": "v3.3.1",
|
||||
@@ -7696,6 +7865,7 @@
|
||||
"faker",
|
||||
"fixtures"
|
||||
],
|
||||
"abandoned": true,
|
||||
"time": "2019-12-12T13:22:17+00:00"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -165,6 +165,7 @@ return [
|
||||
TeamTNT\Scout\TNTSearchScoutServiceProvider::class,
|
||||
Intervention\Image\ImageServiceProvider::class,
|
||||
Laravel\Passport\PassportServiceProvider::class,
|
||||
Madnest\Madzipper\MadzipperServiceProvider::class,
|
||||
|
||||
/*
|
||||
* Package Service Providers...
|
||||
@@ -231,6 +232,8 @@ return [
|
||||
'View' => Illuminate\Support\Facades\View::class,
|
||||
'Image' => Intervention\Image\Facades\Image::class,
|
||||
'Stripe' => Cartalyst\Stripe\Laravel\Facades\Stripe::class,
|
||||
'Crawler' => Jaybizzle\LaravelCrawlerDetect\Facades\LaravelCrawlerDetect::class,
|
||||
'Madzipper' => Madnest\Madzipper\Madzipper::class,
|
||||
],
|
||||
|
||||
'deploy_secret' => env('APP_DEPLOY_SECRET'),
|
||||
|
||||
@@ -1,27 +1,97 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'pages' => [
|
||||
'pages' => [
|
||||
[
|
||||
'visibility' => 1,
|
||||
'visibility' => 0,
|
||||
'title' => 'Terms of Service',
|
||||
'slug' => 'terms-of-service',
|
||||
'content' => 'Laoreet cum hendrerit iaculis arcu phasellus congue et elementum, pharetra risus imperdiet aptent posuere rutrum parturient blandit, dapibus tellus ridiculus potenti aliquam sociis turpis. Nullam commodo eget laoreet risus cursus vel placerat, in dapibus sociis gravida faucibus sodales, fringilla potenti elit semper iaculis ullamcorper. Dignissim vulputate pretium montes pellentesque mollis, consectetur adipiscing curabitur semper sem rhoncus, litora viverra curae proin.',
|
||||
],
|
||||
[
|
||||
'visibility' => 1,
|
||||
'visibility' => 0,
|
||||
'title' => 'Privacy Policy',
|
||||
'slug' => 'privacy-policy',
|
||||
'content' => 'Sit orci justo augue maecenas laoreet consectetur natoque magnis in viverra sagittis, himenaeos urna facilisis mus proin primis diam accumsan tristique inceptos. Primis quisque posuere sit praesent lobortis feugiat semper convallis facilisis, vivamus gravida ligula nostra curae eu donec duis parturient senectus, arcu dolor viverra penatibus natoque cum nisi commodo. Litora sociis mauris justo nullam suspendisse mattis maecenas nascetur congue phasellus cras ultricies posuere donec, dapibus egestas diam lacus ornare montes senectus tincidunt eu taciti sed consequat.',
|
||||
],
|
||||
[
|
||||
'visibility' => 1,
|
||||
'visibility' => 0,
|
||||
'title' => 'Cookie Policy',
|
||||
'slug' => 'cookie-policy',
|
||||
'content' => 'Metus penatibus ligula dolor natoque non habitasse laoreet facilisis, libero vivamus eget semper vulputate interdum integer, phasellus lorem enim blandit consectetur nullam sollicitudin. Hendrerit interdum luctus ut in molestie himenaeos eros cum laoreet parturient est, eu lectus hac et netus viverra dictumst congue elit sem senectus litora, fames scelerisque adipiscing inceptos fringilla montes sociosqu suscipit auctor potenti. Elementum lacus vulputate viverra ac morbi ligula ipsum facilisi, sit eu imperdiet lacinia congue dis vitae.',
|
||||
],
|
||||
],
|
||||
'content' => [
|
||||
'content_regular' => [
|
||||
[
|
||||
'name' => 'section_features',
|
||||
'value' => 0,
|
||||
],
|
||||
[
|
||||
'name' => 'section_feature_boxes',
|
||||
'value' => 0,
|
||||
],
|
||||
[
|
||||
'name' => 'section_get_started',
|
||||
'value' => 0,
|
||||
],
|
||||
[
|
||||
'name' => 'header_title',
|
||||
'value' => 'Simple <span style="color: #41B883">&</span> Powerful Personal Cloud Storage',
|
||||
],
|
||||
[
|
||||
'name' => 'header_description',
|
||||
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
|
||||
],
|
||||
[
|
||||
'name' => 'features_title',
|
||||
'value' => 'The Fastest Growing <span style="color: #41B883">File Manager</span> on the CodeCanyon Market',
|
||||
],
|
||||
[
|
||||
'name' => 'features_description',
|
||||
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
|
||||
],
|
||||
[
|
||||
'name' => 'feature_title_1',
|
||||
'value' => 'Truly Freedom',
|
||||
],
|
||||
[
|
||||
'name' => 'feature_description_1',
|
||||
'value' => 'You have full control over VueFileManager, no third authorities will control your service or usage, only you.',
|
||||
],
|
||||
[
|
||||
'name' => 'feature_title_2',
|
||||
'value' => 'The Sky is the Limit',
|
||||
],
|
||||
[
|
||||
'name' => 'feature_description_2',
|
||||
'value' => 'VueFileManager is cloud storage software. You have to install and running application on your own server hosting.',
|
||||
],
|
||||
[
|
||||
'name' => 'feature_title_3',
|
||||
'value' => 'No Monthly Fees',
|
||||
],
|
||||
[
|
||||
'name' => 'feature_description_3',
|
||||
'value' => 'When you running VueFileManager on your own server hosting, anybody can\'t control your content or resell your user data. Your data is safe.',
|
||||
],
|
||||
[
|
||||
'name' => 'get_started_title',
|
||||
'value' => 'Ready to Get <span style="color: #41B883">Started</span><br> With Us?',
|
||||
],
|
||||
[
|
||||
'name' => 'get_started_description',
|
||||
'value' => 'Your private cloud storage software build on Laravel & Vue.js. No limits & no monthly fees. Truly freedom.',
|
||||
],
|
||||
[
|
||||
'name' => 'footer_content',
|
||||
'value' => '© 2021 Simple & Powerful Personal Cloud Storage. Developed by <a href="https://hi5ve.digital" target="_blank">Hi5Ve.Digital</a>',
|
||||
],
|
||||
[
|
||||
'name' => 'allow_homepage',
|
||||
'value' => 1,
|
||||
],
|
||||
],
|
||||
'content_extended' => [
|
||||
[
|
||||
'name' => 'section_features',
|
||||
'value' => '1',
|
||||
@@ -96,7 +166,11 @@ return [
|
||||
],
|
||||
[
|
||||
'name' => 'footer_content',
|
||||
'value' => '© 2020 Simple & Powerful Personal Cloud Storage. Developed by <a href="https://hi5ve.digital" target="_blank">Hi5Ve.Digital</a>',
|
||||
'value' => '© 2021 Simple & Powerful Personal Cloud Storage. Developed by <a href="https://hi5ve.digital" target="_blank">Hi5Ve.Digital</a>',
|
||||
],
|
||||
[
|
||||
'name' => 'allow_homepage',
|
||||
'value' => 1,
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -41,7 +41,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'queue' => env('SCOUT_QUEUE', false),
|
||||
'queue' => env('SCOUT_QUEUE', true),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
return [
|
||||
|
||||
'version' => '1.7.7',
|
||||
'version' => '1.8.2.3',
|
||||
|
||||
// Define size of chunk uploaded by MB. E.g. integer 128 means chunk size will be 128MB.
|
||||
'chunk_size' => env('CHUNK_SIZE', '128'),
|
||||
];
|
||||
];
|
||||
|
||||
20
database/factories/FileFactory.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Factory $factory */
|
||||
|
||||
use App\FileManagerFile;
|
||||
use Faker\Generator as Faker;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
$factory->define(FileManagerFile::class, function (Faker $faker) {
|
||||
return [
|
||||
'unique_id' => $faker->randomDigit,
|
||||
'user_id' => 0,
|
||||
'folder_id' => 0,
|
||||
'name' => $faker->firstName,
|
||||
'basename' => $faker->lastName,
|
||||
'user_scope' => 'master',
|
||||
'updated_at' => Carbon::now(),
|
||||
'created_at' => Carbon::now()
|
||||
];
|
||||
});
|
||||
17
database/factories/FolderFactory.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Factory $factory */
|
||||
|
||||
use App\FileManagerFolder;
|
||||
use Faker\Generator as Faker;
|
||||
|
||||
$factory->define(FileManagerFolder::class, function (Faker $faker) {
|
||||
return [
|
||||
'id' => $faker->randomDigit,
|
||||
'unique_id' => $faker->randomDigit,
|
||||
'user_id' => 1,
|
||||
'parent_id' => 0,
|
||||
'name' => $faker->sentence,
|
||||
'type' => 'folder',
|
||||
];
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddExpirationAtAttributeToSharesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('shares', function (Blueprint $table) {
|
||||
$table->integer('expire_in')->after('password')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('shares', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddExifDataToFileManagerFilesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('file_manager_files', function (Blueprint $table) {
|
||||
$table->longText('metadata')->after('type')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('file_manager_files', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateTrafficTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('traffic', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->bigInteger('user_id');
|
||||
$table->bigInteger('upload')->default(0);
|
||||
$table->bigInteger('download')->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('traffic');
|
||||
}
|
||||
}
|
||||
36
database/migrations/2020_12_05_090531_create_jobs_table.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateJobsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('jobs', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->string('queue')->index();
|
||||
$table->longText('payload');
|
||||
$table->unsignedTinyInteger('attempts');
|
||||
$table->unsignedInteger('reserved_at')->nullable();
|
||||
$table->unsignedInteger('available_at');
|
||||
$table->unsignedInteger('created_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('jobs');
|
||||
}
|
||||
}
|
||||
34
database/migrations/2020_12_13_155309_create_zips_table.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateZipsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('zips', function (Blueprint $table) {
|
||||
$table->uuid('id')->primary();
|
||||
$table->bigInteger('user_id');
|
||||
$table->string('shared_token')->nullable();
|
||||
$table->text('basename');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('zips');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddTimezoneToUserSettingsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('user_settings', function (Blueprint $table) {
|
||||
$table->decimal('timezone', 10, 1)->after('billing_phone_number')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('user_settings', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddFolderIconOptionsToFileManagerFoldersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('file_manager_folders', function (Blueprint $table) {
|
||||
$table->string('icon_color')->after('user_scope')->nullable();
|
||||
$table->string('icon_emoji')->after('icon_color')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('file_manager_folders', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
||||
70
env.testing
Normal file
@@ -0,0 +1,70 @@
|
||||
APP_NAME=vueFileManager
|
||||
APP_ENV=local
|
||||
APP_KEY=base64:v+s0R2C5q8jYySj3uwrKA8KH8c9JBIZTdXqB2ytk4j8=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
APP_DEMO=false
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
|
||||
DB_CONNECTION=sqlite
|
||||
DB_HOST=null
|
||||
DB_PORT=null
|
||||
DB_DATABASE=database/database.sqlite
|
||||
DB_USERNAME=null
|
||||
DB_PASSWORD=null
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
QUEUE_CONNECTION=sync
|
||||
SESSION_DRIVER=file
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_DRIVER=smtp
|
||||
MAIL_HOST=sty
|
||||
MAIL_PORT=3254
|
||||
MAIL_USERNAME=Milos
|
||||
MAIL_PASSWORD=milos123
|
||||
MAIL_ENCRYPTION=tls
|
||||
MAIL_FROM_ADDRESS="${MAIL_USERNAME}"
|
||||
MAIL_FROM_NAME="${MAIL_USERNAME}"
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=
|
||||
AWS_BUCKET=
|
||||
|
||||
DO_SPACES_KEY=
|
||||
DO_SPACES_SECRET=
|
||||
DO_SPACES_ENDPOINT=
|
||||
DO_SPACES_REGION=
|
||||
DO_SPACES_BUCKET=
|
||||
|
||||
WASABI_KEY=
|
||||
WASABI_SECRET=
|
||||
WASABI_ENDPOINT=
|
||||
WASABI_REGION=
|
||||
WASABI_BUCKET=
|
||||
|
||||
BACKBLAZE_KEY=
|
||||
BACKBLAZE_SECRET=
|
||||
BACKBLAZE_ENDPOINT=
|
||||
BACKBLAZE_REGION=
|
||||
BACKBLAZE_BUCKET=
|
||||
|
||||
PASSPORT_CLIENT_ID=1
|
||||
PASSPORT_CLIENT_SECRET=TqSdKJUbCbC7g5To3Clriw9BMblef0nIdEaI81Q5
|
||||
|
||||
APP_DEPLOY_SECRET=
|
||||
|
||||
CASHIER_LOGGER=stack
|
||||
CASHIER_CURRENCY=
|
||||
STRIPE_KEY=
|
||||
STRIPE_SECRET=
|
||||
STRIPE_WEBHOOK_SECRET=
|
||||
CASHIER_PAYMENT_NOTIFICATION=App\Notifications\ConfirmPayment
|
||||
50
package-lock.json
generated
@@ -10003,6 +10003,53 @@
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
|
||||
},
|
||||
"twemoji": {
|
||||
"version": "13.0.1",
|
||||
"resolved": "https://registry.npmjs.org/twemoji/-/twemoji-13.0.1.tgz",
|
||||
"integrity": "sha512-mrTBq+XpCLM4zm76NJOjLHoQNV9mHdBt3Cba/T5lS1rxn8ArwpqE47mqTocupNlkvcLxoeZJjYSUW0DU5ZwqZg==",
|
||||
"requires": {
|
||||
"fs-extra": "^8.0.1",
|
||||
"jsonfile": "^5.0.0",
|
||||
"twemoji-parser": "13.0.0",
|
||||
"universalify": "^0.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-5.0.0.tgz",
|
||||
"integrity": "sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^0.1.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"twemoji-parser": {
|
||||
"version": "13.0.0",
|
||||
"resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-13.0.0.tgz",
|
||||
"integrity": "sha512-zMaGdskpH8yKjT2RSE/HwE340R4Fm+fbie4AaqjDa4H/l07YUmAvxkSfNl6awVWNRRQ0zdzLQ8SAJZuY5MgstQ=="
|
||||
},
|
||||
"type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
@@ -10124,8 +10171,7 @@
|
||||
"universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
"@fortawesome/vue-fontawesome": "^0.1.10",
|
||||
"lodash": "^4.17.20",
|
||||
"node-sass": "^4.14.1",
|
||||
"twemoji": "^13.0.1",
|
||||
"vee-validate": "^3.3.9",
|
||||
"vue": "^2.6.10",
|
||||
"vue": "^2.6.11",
|
||||
"vue-feather-icons": "^5.1.0",
|
||||
"vue-i18n": "^8.21.0",
|
||||
"vue-router": "^3.4.3",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
AddType video/ogg .ogv
|
||||
AddType video/mp4 .mp4
|
||||
AddType video/webm .webm
|
||||
|
||||
<ifModule mod_headers.c>
|
||||
Header set Connection keep-alive
|
||||
</ifModule>
|
||||
|
||||
14023
public/assets/emojis.json
Normal file
12
public/assets/icons/alphabet.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<svg width="13px" height="15px" viewBox="0 0 13 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="VueFileManager" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||
<g id="Storage-Alert-Copy" transform="translate(-888.000000, -238.000000)" stroke="#000000" stroke-width="1.6">
|
||||
<g id="Sorting-Menu" transform="translate(865.000000, 67.000000)">
|
||||
<g id="alphabet-icon" transform="translate(24.000000, 172.000000)">
|
||||
<polyline id="Path" points="11.1999993 13.1999991 5.59999967 0.199999094 0 13.1999991 5.59999967 0.199999094"></polyline>
|
||||
<line x1="2.25" y1="8" x2="8.75" y2="8" id="Line-2"></line>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 854 B |
|
Before Width: | Height: | Size: 23 KiB |
BIN
public/assets/images/vuefilemanager-og-image.jpg
Normal file
|
After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 665 KiB After Width: | Height: | Size: 649 KiB |
|
Before Width: | Height: | Size: 615 KiB After Width: | Height: | Size: 636 KiB |