diff --git a/.idea/php.xml b/.idea/php.xml index 077cc7d..92abebe 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -121,6 +121,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/.idea/portal.iml b/.idea/portal.iml index 6d96231..64bec86 100644 --- a/.idea/portal.iml +++ b/.idea/portal.iml @@ -7,6 +7,7 @@ + @@ -28,9 +29,13 @@ + + + + @@ -50,7 +55,12 @@ + + + + + @@ -87,6 +97,8 @@ + + @@ -96,9 +108,12 @@ + + + @@ -109,6 +124,7 @@ + diff --git a/Envoy.blade.php b/Envoy.blade.php new file mode 100644 index 0000000..d0f2eb3 --- /dev/null +++ b/Envoy.blade.php @@ -0,0 +1,70 @@ + +@setup + require __DIR__.'/vendor/autoload.php'; + $dotenv = Dotenv\Dotenv::createImmutable(__DIR__, '.env.prod'); + $dotenv->load(); + + $config = new \StdClass; + $config->test_path = "/var/www/html/portal"; + $config->prod_path = "/var/www/html/portal"; + $config->test_branch = "development"; + $config->prod_branch = "production"; + $date = ( new DateTime )->format('Y-m-d H:i:s'); + $dateSave = ( new DateTime )->format('Ymd-Hi'); + $db_host = $_ENV['DB_DATABASE']; + $db_user = $_ENV['DB_USERNAME']; + $db_pass = $_ENV['DB_PASSWORD']; + $rsync = $_ENV['RSYNC_SAV']; + $slack = $_ENV['SLACK_URL']; + +@endsetup + +@servers(['test' => ['raspitest'], 'prod' => ['raspigate']]) + +@story('deploy') + sql-backup + deploy-prod +@endstory + +@task('sql-backup', ['on' => ['prod']]) + cd {{ $config->prod_path }} + mysqldump --user={{ $db_user }} --password={{ $db_pass }} -B {{ $db_host }} > storage/logs/database/save-{{ $db_host }}-{{ $dateSave }}.sql + scp -p storage/logs/database/save-{{ $db_host }}-{{ $dateSave }}.sql {{ $rsync }} +@endtask + +@task('deploy-test', ['on' => ['test']]) + + cd {{ $config->test_path }} +{{-- php artisan down--}} +{{-- git reset --hard HEAD--}} +{{-- git pull origin {{ $config->test_branch }}--}} +{{-- composer install--}} +{{-- npm install--}} +{{-- npm run production--}} +{{-- php artisan migrate --force--}} +{{-- php artisan cache:clear--}} +{{-- php artisan config:cache--}} +{{-- php artisan view:clear--}} +{{-- php artisan optimize--}} +{{-- php artisan up--}} + +@endtask + +@task('deploy-prod', ['on' => ['prod']]) + + cd {{ $config->prod_path }} + php artisan down + git reset --hard HEAD + git pull origin {{ $config->prod_branch }} + composer install + npm install + npm run production + php artisan migrate --force + php artisan optimize + php artisan up + +@endtask + +@finished + @slack($slack, '#envoy', "Deployment on prod: {$date} complete") +@endfinished diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 59c585d..f590bf3 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -36,6 +36,10 @@ class Handler extends ExceptionHandler */ public function report(Throwable $exception) { + if ($this->shouldReport($exception) && app()->bound('sentry')) { + app('sentry')->captureException($exception); + } + parent::report($exception); } diff --git a/app/Http/Controllers/EventController.php b/app/Http/Controllers/EventController.php index 88e9576..e389b4c 100644 --- a/app/Http/Controllers/EventController.php +++ b/app/Http/Controllers/EventController.php @@ -5,6 +5,8 @@ namespace App\Http\Controllers; use App\Http\Requests\EventRequest; use App\Models\Event; use App\Http\Resources\Event as EventResource; +use App\Models\EventGuestsNonUsers; +use App\Models\User; use Illuminate\Http\Request; class EventController extends Controller @@ -12,21 +14,15 @@ class EventController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\Http\Response|object */ public function index() { - // - } + $events = Event::all(); - /** - * Show the form for creating a new resource. - * - * @return \Illuminate\Http\Response - */ - public function create() - { - // + return (EventResource::collection($events)) + ->response() + ->setStatusCode(200); } /** @@ -60,27 +56,22 @@ class EventController extends Controller ->setStatusCode(200); } - /** - * Show the form for editing the specified resource. - * - * @param \App\Models\Event $event - * @return \Illuminate\Http\Response - */ - public function edit(Event $event) - { - // - } - /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param \App\Models\Event $event - * @return \Illuminate\Http\Response + * @return \Illuminate\Http\JsonResponse */ - public function update(Request $request, Event $event) + public function update(EventRequest $request, Event $event) { - // + $this->authorize('update', $event); + + $event->update($request->all()); + + return (new EventResource($event)) + ->response() + ->setStatusCode(200); } /** @@ -91,6 +82,112 @@ class EventController extends Controller */ public function destroy(Event $event) { - // + $this->authorize('delete', $event); + + $event->delete(); + + return response([], 204); + } + + public function inviteUser(Event $event, User $user) + { + + $this->authorize('update', $event); + + $event->guests()->attach($user); + + return (new EventResource($event)) + ->response() + ->setStatusCode(200); + } + + public function removeInviteUser(Event $event, User $user) + { + + $this->authorize('delete', $event); + + $event->guests()->detach($user); + + return (new EventResource($event)) + ->response() + ->setStatusCode(204); + } + + public function addGuestToStaffEvent(Event $event, User $user) + { + + $this->authorize('delete', $event); + + $event->guests()->updateExistingPivot($user, ['is_staff' => true], false); + + return (new EventResource($event)) + ->response() + ->setStatusCode(200); + } + + public function deleteGuestToStaffEvent(Event $event, User $user) + { + $this->authorize('delete', $event); + + $event->guests()->updateExistingPivot($user, ['is_staff' => false], false); + + return (new EventResource($event)) + ->response() + ->setStatusCode(200); + } + + public function userConfirmParticipation(Event $event) + { + $this->authorize('participation', $event); + + $event->guests()->updateExistingPivot(auth()->user(), ['validated_at' => now()->toDateTimeString()], false); + + return (new EventResource($event)) + ->response() + ->setStatusCode(200); + } + + public function userDeleteInvitation(Event $event) + { + $this->authorize('participation', $event); + + $event->guests()->detach(auth()->user()); + + return response([], 204); + } + + public function addGuestWithEmail(Event $event) + { + $data = request()->validate([ + 'email' => 'required|email', + ]); + + $event->emailedGuests()->save(new EventGuestsNonUsers(['email' => $data['email']])); + + return (new EventResource($event)) + ->response() + ->setStatusCode(201); + } + + public function guestCanReadEvent(Event $event) + { + $guest = request()->guest; + + if (!$guest->read_at) { + $guest->update(['read_at' => now()->toDateTimeString()]); + } + return (new EventResource($event)) + ->response() + ->setStatusCode(200); + } + + public function guestCanConfirmEvent(Event $event) + { + $guest = request()->guest; + $guest->update(['validated_at' => now()->toDateTimeString()]); + + return (new EventResource($event)) + ->response() + ->setStatusCode(200); } } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index a6af78b..6ca3a96 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -63,5 +63,6 @@ class Kernel extends HttpKernel 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + 'guest-mail' => \App\Http\Middleware\EventGuestWithEmail::class, ]; } diff --git a/app/Http/Middleware/EventGuestWithEmail.php b/app/Http/Middleware/EventGuestWithEmail.php new file mode 100644 index 0000000..459cf18 --- /dev/null +++ b/app/Http/Middleware/EventGuestWithEmail.php @@ -0,0 +1,32 @@ +validate([ + 'email' => 'required|email', + 'token' => 'required|uuid', + ]); + + $guest = EventGuestsNonUsers::where('email', $data['email'])->where('token', $data['token'])->first(); + if ($guest) { + $request->guest = $guest; + return $next($request); + } + + return response([], 403); + } +} diff --git a/app/Http/Requests/EventRequest.php b/app/Http/Requests/EventRequest.php index 879f6ab..e21ef46 100644 --- a/app/Http/Requests/EventRequest.php +++ b/app/Http/Requests/EventRequest.php @@ -27,8 +27,9 @@ class EventRequest extends FormRequest 'name' => 'required', 'description' => 'nullable|string', 'category_id' => 'required|exists:event_categories,id', + 'private' => 'boolean', 'start_date' => 'required|date', - 'end_date' => 'date|after_or_equal:start_date', + 'end_date' => 'date|after_or_equal:start_date|nullable', 'location' => 'string|nullable' ]; } diff --git a/app/Http/Resources/Event.php b/app/Http/Resources/Event.php index d1d33b3..decb39c 100644 --- a/app/Http/Resources/Event.php +++ b/app/Http/Resources/Event.php @@ -2,6 +2,9 @@ namespace App\Http\Resources; +use App\Http\Resources\User as UserResource; +use App\Http\Resources\EventCategory as EventCategoryResource; +use App\Http\Resources\EventGuestWithoutEmail as GuestsWithoutEmailResource; use Illuminate\Http\Resources\Json\JsonResource; class Event extends JsonResource @@ -25,16 +28,16 @@ class Event extends JsonResource 'start_date' => $this->start_date, 'end_date' => $this->end_date, 'location' => $this->location, - 'category' => [ - 'data' => [ - 'category_id' => $this->category_id - ], + 'category' => new EventCategoryResource($this->category), + 'invitations' => UserResource::collection($this->guests), + 'invitations-with-email' => [ + 'data' => GuestsWithoutEmailResource::collection($this->emailedGuests) ], ] ], ], 'links' => [ - 'self' => url('/events/'.$this->id), + 'self' => $this->path(), ] ]; } diff --git a/app/Http/Resources/EventGuestWithoutEmail.php b/app/Http/Resources/EventGuestWithoutEmail.php new file mode 100644 index 0000000..1206d56 --- /dev/null +++ b/app/Http/Resources/EventGuestWithoutEmail.php @@ -0,0 +1,23 @@ + $this->email, + 'read_at' => $this->read_at, + 'validated_at' => $this->validated_at, + ]; + } +} diff --git a/app/Http/Resources/User.php b/app/Http/Resources/User.php index 08402fe..6821122 100644 --- a/app/Http/Resources/User.php +++ b/app/Http/Resources/User.php @@ -27,6 +27,12 @@ class User extends JsonResource 'thumbnail_cover_image' => new ImageResource($this->thumbnailImage), 'last_login' => optional($this->login_at)->diffForHumans(), 'is_admin' => $this->isAdmin(), + 'is_staff' => $this->whenPivotLoaded('event_guest', function () { + return (int) $this->pivot->is_staff; + }), + 'validated_at' => $this->whenPivotLoaded('event_guest', function () { + return (int) $this->pivot->validated_at; + }), ], ], 'links' => [ diff --git a/app/Models/Event.php b/app/Models/Event.php index bc96b28..0b2b137 100644 --- a/app/Models/Event.php +++ b/app/Models/Event.php @@ -3,8 +3,33 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; +use Illuminate\Database\Eloquent\Relations\HasMany; class Event extends Model { protected $guarded = []; + + public function path() + { + return '/events/' . $this->id; + } + + public function category() :BelongsTo + { + return $this->belongsTo(EventCategory::class, 'category_id'); + } + + public function guests() :BelongsToMany + { + return $this->belongsToMany(User::class, 'event_guest') + ->withPivot('is_staff', 'validated_at') + ->withTimestamps(); + } + + public function emailedGuests() :HasMany + { + return $this->hasMany(EventGuestsNonUsers::class, 'event_id'); + } } diff --git a/app/Models/EventGuestsNonUsers.php b/app/Models/EventGuestsNonUsers.php new file mode 100644 index 0000000..d418e06 --- /dev/null +++ b/app/Models/EventGuestsNonUsers.php @@ -0,0 +1,12 @@ +hasMany(Event::class); } + + public function invitedEvent(): BelongsToMany + { + return $this->belongsToMany(Event::class, 'event_guest', 'user_id', 'event_id') + ->withPivot('is_staff', 'validated_at') + ->withTimestamps(); + } } diff --git a/app/Policies/EventPolicy.php b/app/Policies/EventPolicy.php new file mode 100644 index 0000000..1f1d2ec --- /dev/null +++ b/app/Policies/EventPolicy.php @@ -0,0 +1,122 @@ +id == $event->user_id) { + return true; + } else { + $testedUser = $event->guests()->where('users.id', $user->id)->first(); + if ($testedUser !== null) { + if($testedUser->pivot->is_staff) { + return $testedUser->pivot->is_staff; + } else if (!$event->private) { + return true; + } + } + } + return false; + } + + /** + * Determine whether the user can delete the model. + * + * @param \App\User $user + * @param \App\Models\Event $event + * @return mixed + */ + public function delete(User $user, Event $event) + { + return $user->id == $event->user_id; + } + + /** + * Determine whether the user can restore the model. + * + * @param \App\User $user + * @param \App\Models\Event $event + * @return mixed + */ + public function restore(User $user, Event $event) + { + return false; + } + + /** + * Determine whether the user can permanently delete the model. + * + * @param \App\User $user + * @param \App\Models\Event $event + * @return mixed + */ + public function forceDelete(User $user, Event $event) + { + return false; + } + + /** + * Determine whether the guest can permanently delete invitation. + * + * @param \App\User $user + * @param \App\Models\Event $event + * @return mixed + */ + public function participation(User $user, Event $event) + { + $testedUser = $event->guests()->where('users.id', $user->id)->first(); + if ($testedUser !== null) { + return true; + } + return false; + } +} diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index ef64ad5..f5ae626 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -19,6 +19,7 @@ class AuthServiceProvider extends ServiceProvider 'App\Models\Memo' => 'App\Policies\MemoPolicy', 'App\Models\ToDoList' => 'App\Policies\ToDoListPolicy', 'App\Models\Bookmark' => 'App\Policies\BookmarkPolicy', + 'App\Models\Event' => 'App\Policies\EventPolicy', ]; /** diff --git a/composer.json b/composer.json index 6983ee4..6e50943 100644 --- a/composer.json +++ b/composer.json @@ -14,9 +14,13 @@ "guzzlehttp/guzzle": "^7.0.1", "intervention/image": "^2.5", "laravel/framework": "^8.0", + "laravel/legacy-factories": "^1.0", "laravel/passport": "^10.0", + "laravel/slack-notification-channel": "^2.2", "laravel/tinker": "^2.0", - "laravel/ui": "^2.0" + "laravel/ui": "^2.0", + "sentry/sentry-laravel": "^2.0", + "vlucas/phpdotenv": "^5.2" }, "require-dev": { "facade/ignition": "^2.3.6", diff --git a/composer.lock b/composer.lock index fb32ce8..fa4e866 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5eb5309302a9537ceba55622220336a9", + "content-hash": "32d5c8dc4479b4dcb3acfbe92909e029", "packages": [ { "name": "asm89/stack-cors", @@ -110,6 +110,137 @@ ], "time": "2020-08-18T23:57:15+00:00" }, + { + "name": "clue/stream-filter", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/clue/php-stream-filter.git", + "reference": "aeb7d8ea49c7963d3b581378955dbf5bc49aa320" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/clue/php-stream-filter/zipball/aeb7d8ea49c7963d3b581378955dbf5bc49aa320", + "reference": "aeb7d8ea49c7963d3b581378955dbf5bc49aa320", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "psr-4": { + "Clue\\StreamFilter\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "A simple and modern approach to stream filtering in PHP", + "homepage": "https://github.com/clue/php-stream-filter", + "keywords": [ + "bucket brigade", + "callback", + "filter", + "php_user_filter", + "stream", + "stream_filter_append", + "stream_filter_register" + ], + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2020-10-02T12:38:20+00:00" + }, + { + "name": "composer/package-versions-deprecated", + "version": "1.11.99", + "source": { + "type": "git", + "url": "https://github.com/composer/package-versions-deprecated.git", + "reference": "c8c9aa8a14cc3d3bec86d0a8c3fa52ea79936855" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/c8c9aa8a14cc3d3bec86d0a8c3fa52ea79936855", + "reference": "c8c9aa8a14cc3d3bec86d0a8c3fa52ea79936855", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1.0 || ^2.0", + "php": "^7 || ^8" + }, + "replace": { + "ocramius/package-versions": "1.11.99" + }, + "require-dev": { + "composer/composer": "^1.9.3 || ^2.0@dev", + "ext-zip": "^1.13", + "phpunit/phpunit": "^6.5 || ^7" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-08-25T05:50:16+00:00" + }, { "name": "defuse/php-encryption", "version": "v2.2.1", @@ -928,6 +1059,56 @@ ], "time": "2019-07-01T23:21:34+00:00" }, + { + "name": "http-interop/http-factory-guzzle", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/http-interop/http-factory-guzzle.git", + "reference": "34861658efb9899a6618cef03de46e2a52c80fc0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/http-interop/http-factory-guzzle/zipball/34861658efb9899a6618cef03de46e2a52c80fc0", + "reference": "34861658efb9899a6618cef03de46e2a52c80fc0", + "shasum": "" + }, + "require": { + "guzzlehttp/psr7": "^1.4.2", + "psr/http-factory": "^1.0" + }, + "provide": { + "psr/http-factory-implementation": "^1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.5", + "phpunit/phpunit": "^6.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Factory\\Guzzle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "An HTTP Factory using Guzzle PSR7", + "keywords": [ + "factory", + "http", + "psr-17", + "psr-7" + ], + "time": "2018-07-31T19:32:56+00:00" + }, { "name": "intervention/image", "version": "2.5.1", @@ -998,6 +1179,57 @@ ], "time": "2019-11-02T09:15:47+00:00" }, + { + "name": "jean85/pretty-package-versions", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "a917488320c20057da87f67d0d40543dd9427f7a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/a917488320c20057da87f67d0d40543dd9427f7a", + "reference": "a917488320c20057da87f67d0d40543dd9427f7a", + "shasum": "" + }, + "require": { + "composer/package-versions-deprecated": "^1.8.0", + "php": "^7.0|^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0|^8.5|^9.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A wrapper for ocramius/package-versions to get pretty versions strings", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "time": "2020-09-14T08:43:34+00:00" + }, { "name": "laravel/framework", "version": "v8.0.0", @@ -1161,6 +1393,58 @@ ], "time": "2020-09-08T15:15:32+00:00" }, + { + "name": "laravel/legacy-factories", + "version": "v1.0.4", + "source": { + "type": "git", + "url": "https://github.com/laravel/legacy-factories.git", + "reference": "57117fdf788520a04c99f86205155f2799271af9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/legacy-factories/zipball/57117fdf788520a04c99f86205155f2799271af9", + "reference": "57117fdf788520a04c99f86205155f2799271af9", + "shasum": "" + }, + "require": { + "illuminate/macroable": "^8.0", + "php": "^7.3", + "symfony/finder": "^3.4|^4.0|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + }, + "laravel": { + "providers": [ + "Illuminate\\Database\\Eloquent\\LegacyFactoryServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "helpers.php" + ], + "psr-4": { + "Illuminate\\Database\\Eloquent\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The legacy version of the Laravel Eloquent factories.", + "homepage": "http://laravel.com", + "time": "2020-06-09T15:09:18+00:00" + }, { "name": "laravel/passport", "version": "v10.0.0", @@ -1233,6 +1517,63 @@ ], "time": "2020-09-08T15:27:48+00:00" }, + { + "name": "laravel/slack-notification-channel", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/slack-notification-channel.git", + "reference": "98e0fe5c8dda645e6af914285af7b742e167462a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/98e0fe5c8dda645e6af914285af7b742e167462a", + "reference": "98e0fe5c8dda645e6af914285af7b742e167462a", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0|^7.0", + "illuminate/notifications": "~5.8.0|^6.0|^7.0|^8.0", + "php": "^7.1.3" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Illuminate\\Notifications\\SlackChannelServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Notifications\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Slack Notification Channel for laravel.", + "keywords": [ + "laravel", + "notifications", + "slack" + ], + "time": "2020-08-25T18:21:34+00:00" + }, { "name": "laravel/tinker", "version": "v2.4.2", @@ -1880,16 +2221,16 @@ }, { "name": "nesbot/carbon", - "version": "2.39.1", + "version": "2.39.2", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "7af467873250583cc967a59ee9df29fabab193c1" + "reference": "326efde1bc09077a26cb77f6e2e32e13f06c27f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7af467873250583cc967a59ee9df29fabab193c1", - "reference": "7af467873250583cc967a59ee9df29fabab193c1", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/326efde1bc09077a26cb77f6e2e32e13f06c27f2", + "reference": "326efde1bc09077a26cb77f6e2e32e13f06c27f2", "shasum": "" }, "require": { @@ -1965,7 +2306,7 @@ "type": "tidelift" } ], - "time": "2020-09-04T13:11:37+00:00" + "time": "2020-09-10T12:16:42+00:00" }, { "name": "nikic/php-parser", @@ -2198,6 +2539,273 @@ ], "time": "2018-07-02T15:55:56+00:00" }, + { + "name": "php-http/client-common", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/client-common.git", + "reference": "e37e46c610c87519753135fb893111798c69076a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/client-common/zipball/e37e46c610c87519753135fb893111798c69076a", + "reference": "e37e46c610c87519753135fb893111798c69076a", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/httplug": "^2.0", + "php-http/message": "^1.6", + "php-http/message-factory": "^1.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0", + "symfony/options-resolver": "^2.6 || ^3.4.20 || ~4.0.15 || ~4.1.9 || ^4.2.1 || ^5.0", + "symfony/polyfill-php80": "^1.17" + }, + "require-dev": { + "doctrine/instantiator": "^1.1", + "guzzlehttp/psr7": "^1.4", + "nyholm/psr7": "^1.2", + "phpspec/phpspec": "^5.1 || ^6.0", + "phpspec/prophecy": "^1.10.2", + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.3" + }, + "suggest": { + "ext-json": "To detect JSON responses with the ContentTypePlugin", + "ext-libxml": "To detect XML responses with the ContentTypePlugin", + "php-http/cache-plugin": "PSR-6 Cache plugin", + "php-http/logger-plugin": "PSR-3 Logger plugin", + "php-http/stopwatch-plugin": "Symfony Stopwatch plugin" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Client\\Common\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Common HTTP Client implementations and tools for HTTPlug", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "common", + "http", + "httplug" + ], + "time": "2020-07-21T10:04:13+00:00" + }, + { + "name": "php-http/discovery", + "version": "1.12.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "4366bf1bc39b663aa87459bd725501d2f1988b6c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/4366bf1bc39b663aa87459bd725501d2f1988b6c", + "reference": "4366bf1bc39b663aa87459bd725501d2f1988b6c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0" + }, + "require-dev": { + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1", + "puli/composer-plugin": "1.0.0-beta10" + }, + "suggest": { + "php-http/message": "Allow to use Guzzle, Diactoros or Slim Framework factories", + "puli/composer-plugin": "Sets up Puli which is recommended for Discovery to work. Check http://docs.php-http.org/en/latest/discovery.html for more details." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds installed HTTPlug implementations and PSR-7 message factories", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr7" + ], + "time": "2020-09-22T13:31:04+00:00" + }, + { + "name": "php-http/httplug", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/httplug.git", + "reference": "191a0a1b41ed026b717421931f8d3bd2514ffbf9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/httplug/zipball/191a0a1b41ed026b717421931f8d3bd2514ffbf9", + "reference": "191a0a1b41ed026b717421931f8d3bd2514ffbf9", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/promise": "^1.1", + "psr/http-client": "^1.0", + "psr/http-message": "^1.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.1", + "phpspec/phpspec": "^5.1 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eric GELOEN", + "email": "geloen.eric@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "HTTPlug, the HTTP client abstraction for PHP", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "http" + ], + "time": "2020-07-13T15:43:23+00:00" + }, + { + "name": "php-http/message", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/message.git", + "reference": "2c7256e3c1aba0bfca70f099810f1c7712e00945" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/message/zipball/2c7256e3c1aba0bfca70f099810f1c7712e00945", + "reference": "2c7256e3c1aba0bfca70f099810f1c7712e00945", + "shasum": "" + }, + "require": { + "clue/stream-filter": "^1.4.1", + "php": "^7.1", + "php-http/message-factory": "^1.0.2", + "psr/http-message": "^1.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0" + }, + "require-dev": { + "akeneo/phpspec-skip-example-extension": "^1.0", + "coduo/phpspec-data-provider-extension": "^1.0", + "ergebnis/composer-normalize": "^2.1", + "ext-zlib": "*", + "guzzlehttp/psr7": "^1.0", + "henrikbjorn/phpspec-code-coverage": "^1.0", + "phpspec/phpspec": "^2.4", + "slim/slim": "^3.0", + "zendframework/zend-diactoros": "^1.0" + }, + "suggest": { + "ext-zlib": "Used with compressor/decompressor streams", + "guzzlehttp/psr7": "Used with Guzzle PSR-7 Factories", + "slim/slim": "Used with Slim Framework PSR-7 implementation", + "zendframework/zend-diactoros": "Used with Diactoros Factories" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Message\\": "src/" + }, + "files": [ + "src/filters.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "HTTP Message related tools", + "homepage": "http://php-http.org", + "keywords": [ + "http", + "message", + "psr-7" + ], + "time": "2020-08-17T06:33:14+00:00" + }, { "name": "php-http/message-factory", "version": "v1.0.2", @@ -2248,6 +2856,59 @@ ], "time": "2015-12-19T14:08:53+00:00" }, + { + "name": "php-http/promise", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/promise.git", + "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/promise/zipball/4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", + "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.3.2", + "phpspec/phpspec": "^5.1.2 || ^6.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joel Wurtz", + "email": "joel.wurtz@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Promise used for asynchronous HTTP requests", + "homepage": "http://httplug.io", + "keywords": [ + "promise" + ], + "time": "2020-07-07T09:29:14+00:00" + }, { "name": "phpoption/phpoption", "version": "1.7.5", @@ -2873,16 +3534,16 @@ }, { "name": "ramsey/collection", - "version": "1.1.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "044184884e3c803e4cbb6451386cb71562939b18" + "reference": "24d93aefb2cd786b7edd9f45b554aea20b28b9b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/044184884e3c803e4cbb6451386cb71562939b18", - "reference": "044184884e3c803e4cbb6451386cb71562939b18", + "url": "https://api.github.com/repos/ramsey/collection/zipball/24d93aefb2cd786b7edd9f45b554aea20b28b9b1", + "reference": "24d93aefb2cd786b7edd9f45b554aea20b28b9b1", "shasum": "" }, "require": { @@ -2938,7 +3599,7 @@ "type": "github" } ], - "time": "2020-08-11T00:57:21+00:00" + "time": "2020-09-10T20:58:17+00:00" }, { "name": "ramsey/uuid", @@ -3027,6 +3688,240 @@ ], "time": "2020-08-18T17:17:46+00:00" }, + { + "name": "sentry/sdk", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/getsentry/sentry-php-sdk.git", + "reference": "908ea3fd0e7a19ccf4b53d1c247c44231595d008" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getsentry/sentry-php-sdk/zipball/908ea3fd0e7a19ccf4b53d1c247c44231595d008", + "reference": "908ea3fd0e7a19ccf4b53d1c247c44231595d008", + "shasum": "" + }, + "require": { + "http-interop/http-factory-guzzle": "^1.0", + "sentry/sentry": "^3.0", + "symfony/http-client": "^4.3|^5.0" + }, + "type": "metapackage", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sentry", + "email": "accounts@sentry.io" + } + ], + "description": "This is a metapackage shipping sentry/sentry with a recommended HTTP client.", + "homepage": "http://sentry.io", + "keywords": [ + "crash-reporting", + "crash-reports", + "error-handler", + "error-monitoring", + "log", + "logging", + "sentry" + ], + "funding": [ + { + "url": "https://sentry.io/", + "type": "custom" + }, + { + "url": "https://sentry.io/pricing/", + "type": "custom" + } + ], + "time": "2020-09-28T07:49:07+00:00" + }, + { + "name": "sentry/sentry", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/getsentry/sentry-php.git", + "reference": "a35c6c71693a72f2fedb9b6f9644ced52268771d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/a35c6c71693a72f2fedb9b6f9644ced52268771d", + "reference": "a35c6c71693a72f2fedb9b6f9644ced52268771d", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "guzzlehttp/promises": "^1.3", + "guzzlehttp/psr7": "^1.6", + "jean85/pretty-package-versions": "^1.5", + "ocramius/package-versions": "^1.8", + "php": "^7.2", + "php-http/async-client-implementation": "^1.0", + "php-http/client-common": "^1.5|^2.0", + "php-http/discovery": "^1.6.1", + "php-http/httplug": "^1.1|^2.0", + "php-http/message": "^1.5", + "psr/http-factory": "^1.0", + "psr/http-message-implementation": "^1.0", + "psr/log": "^1.0", + "symfony/options-resolver": "^3.4.4|^4.0|^5.0", + "symfony/polyfill-php80": "^1.17", + "symfony/polyfill-uuid": "^1.13.1" + }, + "conflict": { + "php-http/client-common": "1.8.0", + "raven/raven": "*" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16", + "http-interop/http-factory-guzzle": "^1.0", + "monolog/monolog": "^1.3|^2.0", + "php-http/mock-client": "^1.3", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.5.18", + "symfony/phpunit-bridge": "^4.3|^5.0", + "vimeo/psalm": "^3.4" + }, + "suggest": { + "monolog/monolog": "Allow sending log messages to Sentry by using the included Monolog handler." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Sentry\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sentry", + "email": "accounts@sentry.io" + } + ], + "description": "A PHP SDK for Sentry (http://sentry.io)", + "homepage": "http://sentry.io", + "keywords": [ + "crash-reporting", + "crash-reports", + "error-handler", + "error-monitoring", + "log", + "logging", + "sentry" + ], + "funding": [ + { + "url": "https://sentry.io/", + "type": "custom" + }, + { + "url": "https://sentry.io/pricing/", + "type": "custom" + } + ], + "time": "2020-10-02T14:16:36+00:00" + }, + { + "name": "sentry/sentry-laravel", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/getsentry/sentry-laravel.git", + "reference": "3c6b1da08087f428ab1a188af35483eb76ef6b1e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/3c6b1da08087f428ab1a188af35483eb76ef6b1e", + "reference": "3c6b1da08087f428ab1a188af35483eb76ef6b1e", + "shasum": "" + }, + "require": { + "illuminate/support": "5.0 - 5.8 | ^6.0 | ^7.0 | ^8.0", + "php": "^7.2", + "sentry/sdk": "^3.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "2.16.*", + "laravel/framework": "^7.0", + "mockery/mockery": "1.3.*", + "orchestra/testbench": "^5.0", + "phpunit/phpunit": "^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev", + "dev-0.x": "0.x-dev" + }, + "laravel": { + "providers": [ + "Sentry\\Laravel\\ServiceProvider", + "Sentry\\Laravel\\Tracing\\ServiceProvider" + ], + "aliases": { + "Sentry": "Sentry\\Laravel\\Facade" + } + } + }, + "autoload": { + "psr-0": { + "Sentry\\Laravel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Sentry", + "email": "accounts@sentry.io" + } + ], + "description": "Laravel SDK for Sentry (https://sentry.io)", + "homepage": "https://sentry.io", + "keywords": [ + "crash-reporting", + "crash-reports", + "error-handler", + "error-monitoring", + "laravel", + "log", + "logging", + "sentry" + ], + "funding": [ + { + "url": "https://sentry.io/", + "type": "custom" + }, + { + "url": "https://sentry.io/pricing/", + "type": "custom" + } + ], + "time": "2020-10-01T12:14:37+00:00" + }, { "name": "swiftmailer/swiftmailer", "version": "v6.2.3", @@ -3609,6 +4504,167 @@ ], "time": "2020-08-17T10:01:29+00:00" }, + { + "name": "symfony/http-client", + "version": "v5.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "4a5f2750b54e3cfc5b6711dd78fdbac6563ee7bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/4a5f2750b54e3cfc5b6711dd78fdbac6563ee7bf", + "reference": "4a5f2750b54e3cfc5b6711dd78fdbac6563ee7bf", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/log": "^1.0", + "symfony/http-client-contracts": "^2.2", + "symfony/polyfill-php73": "^1.11", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.0|^2" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "1.1" + }, + "require-dev": { + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.3.1", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/http-kernel": "^4.4.13|^5.1.5", + "symfony/process": "^4.4|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpClient component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-27T03:44:28+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "3a5d0fe7908daaa23e3dbf4cee3ba4bfbb19fdd3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/3a5d0fe7908daaa23e3dbf4cee3ba4bfbb19fdd3", + "reference": "3a5d0fe7908daaa23e3dbf4cee3ba4bfbb19fdd3", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "suggest": { + "symfony/http-client-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-07T11:33:47+00:00" + }, { "name": "symfony/http-foundation", "version": "v5.1.5", @@ -3874,6 +4930,76 @@ ], "time": "2020-08-17T10:01:29+00:00" }, + { + "name": "symfony/options-resolver", + "version": "v5.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "4c7e155bf7d93ea4ba3824d5a14476694a5278dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/4c7e155bf7d93ea4ba3824d5a14476694a5278dd", + "reference": "4c7e155bf7d93ea4ba3824d5a14476694a5278dd", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php80": "^1.15" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony OptionsResolver Component", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-27T03:44:28+00:00" + }, { "name": "symfony/polyfill-ctype", "version": "v1.18.1", @@ -4654,6 +5780,83 @@ ], "time": "2020-07-14T12:35:20+00:00" }, + { + "name": "symfony/polyfill-uuid", + "version": "v1.18.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "da48e2cccd323e48c16c26481bf5800f6ab1c49d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/da48e2cccd323e48c16c26481bf5800f6ab1c49d", + "reference": "da48e2cccd323e48c16c26481bf5800f6ab1c49d", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0|~9.99", + "php": ">=5.3.3" + }, + "suggest": { + "ext-uuid": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.18-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Uuid\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for uuid functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "uuid" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-07-14T12:35:20+00:00" + }, { "name": "symfony/process", "version": "v5.1.5", @@ -5357,16 +6560,16 @@ }, { "name": "vlucas/phpdotenv", - "version": "v5.1.0", + "version": "v5.2.0", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "448c76d7a9e30c341ff5bc367a923af74ae18467" + "reference": "fba64139db67123c7a57072e5f8d3db10d160b66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/448c76d7a9e30c341ff5bc367a923af74ae18467", - "reference": "448c76d7a9e30c341ff5bc367a923af74ae18467", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/fba64139db67123c7a57072e5f8d3db10d160b66", + "reference": "fba64139db67123c7a57072e5f8d3db10d160b66", "shasum": "" }, "require": { @@ -5389,7 +6592,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-master": "5.2-dev" } }, "autoload": { @@ -5429,7 +6632,7 @@ "type": "tidelift" } ], - "time": "2020-07-14T19:26:25+00:00" + "time": "2020-09-14T15:57:31+00:00" }, { "name": "voku/portable-ascii", @@ -6681,6 +7884,7 @@ "keywords": [ "tokenizer" ], + "abandoned": true, "time": "2019-09-17T06:23:10+00:00" }, { diff --git a/config/sentry.php b/config/sentry.php new file mode 100644 index 0000000..7fec6c7 --- /dev/null +++ b/config/sentry.php @@ -0,0 +1,34 @@ + env('SENTRY_LARAVEL_DSN', env('SENTRY_DSN')), + + // capture release as git sha + // 'release' => trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')), + + // When left empty or `null` the Laravel environment will be used + 'environment' => env('SENTRY_ENVIRONMENT'), + + 'breadcrumbs' => [ + // Capture Laravel logs in breadcrumbs + 'logs' => true, + + // Capture SQL queries in breadcrumbs + 'sql_queries' => true, + + // Capture bindings on SQL queries logged in breadcrumbs + 'sql_bindings' => true, + + // Capture queue job information in breadcrumbs + 'queue_info' => true, + + // Capture command information in breadcrumbs + 'command_info' => true, + ], + + // @see: https://docs.sentry.io/error-reporting/configuration/?platform=php#send-default-pii + 'send_default_pii' => false, + + 'traces_sample_rate' => (float)(env('SENTRY_TRACES_SAMPLE_RATE', 0.0)), +]; diff --git a/database/factories/EventCategoryFactory.php b/database/factories/EventCategoryFactory.php new file mode 100644 index 0000000..aa770cd --- /dev/null +++ b/database/factories/EventCategoryFactory.php @@ -0,0 +1,13 @@ +define(EventCategory::class, function (Faker $faker) { + return [ + 'name' => $faker->words(3, [false]), + 'description' => $faker->words(rand(10, 30), [false]), + ]; +}); diff --git a/database/factories/EventFactory.php b/database/factories/EventFactory.php new file mode 100644 index 0000000..ef73b73 --- /dev/null +++ b/database/factories/EventFactory.php @@ -0,0 +1,24 @@ +define(Event::class, function (Faker $faker) { + $startDate = $faker->dateTimeThisMonth; + $endDate = $faker->dateTimeBetween($startDate, date_add($startDate, date_interval_create_from_date_string('10 days'))); + $endDate = (rand(0, 1) === 0) ? null : $endDate; + return [ + 'user_id' => factory(User::class), + 'category_id' => factory(EventCategory::class), + 'name' => $faker->words(3, [false]), + 'description' => $faker->words(rand(10, 300), [false]), + 'private' => !(rand(0,1)), + 'start_date' => $startDate, + 'end_date' => $endDate, + 'location' => $faker->city, + ]; +}); diff --git a/database/migrations/2020_08_15_085105_create_events_table.php b/database/migrations/2020_08_15_085105_create_events_table.php index 6239ca5..f592391 100644 --- a/database/migrations/2020_08_15_085105_create_events_table.php +++ b/database/migrations/2020_08_15_085105_create_events_table.php @@ -19,6 +19,7 @@ class CreateEventsTable extends Migration $table->unsignedBigInteger('category_id'); $table->string('name'); $table->text('description')->nullable(); + $table->boolean('private')->default(true); $table->timestamp('start_date'); $table->timestamp('end_date')->nullable(); $table->string('location')->nullable(); diff --git a/database/migrations/2020_08_15_173607_create_event_guest_table.php b/database/migrations/2020_08_15_173607_create_event_guest_table.php new file mode 100644 index 0000000..4c9f852 --- /dev/null +++ b/database/migrations/2020_08_15_173607_create_event_guest_table.php @@ -0,0 +1,43 @@ +id(); + $table->foreignId('event_id'); + $table->foreignId('user_id'); + $table->boolean('is_staff')->default(false); + $table->timestamp('validated_at')->nullable(); + $table->timestamps(); + + $table->foreign('event_id')->references('id')->on('events'); + $table->foreign('user_id')->references('id')->on('users'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('event_guest', function (Blueprint $table) { + $table->dropForeign(['event_id']); + $table->dropForeign(['user_id']); + }); + + Schema::dropIfExists('event_guest'); + } +} diff --git a/database/migrations/2020_08_20_131741_create_event_non_user_guests_table.php b/database/migrations/2020_08_20_131741_create_event_non_user_guests_table.php new file mode 100644 index 0000000..98ad33b --- /dev/null +++ b/database/migrations/2020_08_20_131741_create_event_non_user_guests_table.php @@ -0,0 +1,46 @@ +id(); + $table->foreignId('event_id'); + $table->string('email'); + $table->uuid('token')->default(\Illuminate\Support\Str::uuid()); + $table->timestamp('read_at')->nullable(); + $table->timestamp('validated_at')->nullable(); + $table->timestamps(); + + $table->foreign('event_id') + ->references('id') + ->on('events') + ->onDelete('restrict') + ->onUpdate('restrict'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('event_non_user_guests', function (Blueprint $table) { + $table->dropForeign(['event_id']); + }); + + Schema::dropIfExists('event_non_user_guests'); + } +} diff --git a/deploy.sh b/deploy.sh index dcd3b66..0feca03 100644 --- a/deploy.sh +++ b/deploy.sh @@ -48,6 +48,7 @@ if [ -z "$1" ]; then composer install php artisan migrate --force + php artisan db:seed php artisan optimize npm install --no-progress @@ -79,6 +80,7 @@ elif [ "$1" = git-prod ]; then composer install php artisan migrate --force + php artisan db:seed php artisan optimize fi diff --git a/resources/js/components/CheckBoxField.vue b/resources/js/components/Form/CheckBoxField.vue similarity index 100% rename from resources/js/components/CheckBoxField.vue rename to resources/js/components/Form/CheckBoxField.vue diff --git a/resources/js/components/Form/DateTimeField.vue b/resources/js/components/Form/DateTimeField.vue new file mode 100644 index 0000000..45b2954 --- /dev/null +++ b/resources/js/components/Form/DateTimeField.vue @@ -0,0 +1,85 @@ + + + + diff --git a/resources/js/components/InputField.vue b/resources/js/components/Form/InputField.vue similarity index 91% rename from resources/js/components/InputField.vue rename to resources/js/components/Form/InputField.vue index 0ef175c..f005f6a 100644 --- a/resources/js/components/InputField.vue +++ b/resources/js/components/Form/InputField.vue @@ -2,7 +2,7 @@
-

Error Here

+

Error Here

@@ -55,8 +55,8 @@ export default { } }, errorClassObject: function () { - return { - 'error-field': this.hasError + if (this.hasError) { + return 'border-red' } } }, diff --git a/resources/js/components/Form/SelectorField.vue b/resources/js/components/Form/SelectorField.vue new file mode 100644 index 0000000..343d462 --- /dev/null +++ b/resources/js/components/Form/SelectorField.vue @@ -0,0 +1,62 @@ + + + diff --git a/resources/js/components/TextAreaField.vue b/resources/js/components/Form/TextAreaField.vue similarity index 86% rename from resources/js/components/TextAreaField.vue rename to resources/js/components/Form/TextAreaField.vue index 935e133..d3b6fff 100644 --- a/resources/js/components/TextAreaField.vue +++ b/resources/js/components/Form/TextAreaField.vue @@ -1,6 +1,6 @@ @@ -60,8 +60,8 @@ export default { } }, errorClassObject: function () { - return { - 'error-field': this.hasError + if (this.hasError) { + return 'border-red' } } }, diff --git a/resources/js/components/UploadableImage.vue b/resources/js/components/Form/UploadableImage.vue similarity index 100% rename from resources/js/components/UploadableImage.vue rename to resources/js/components/Form/UploadableImage.vue diff --git a/resources/js/components/Nav.vue b/resources/js/components/Nav.vue index 5c252ed..25e693d 100644 --- a/resources/js/components/Nav.vue +++ b/resources/js/components/Nav.vue @@ -17,6 +17,10 @@ Bookmarks + + + Evénements + Jeux diff --git a/resources/js/router.js b/resources/js/router.js index 49a1c34..010d10d 100644 --- a/resources/js/router.js +++ b/resources/js/router.js @@ -15,6 +15,10 @@ import BookmarkIndex from './views/Bookmark/BookmarkIndex' import GameIndex from './views/Games/GameIndex' import Hangman from './views/Games/HangMan/Hangman' import Quizz from './views/Games/Quizz/Quizz' +import EventIndex from './views/Event/EventIndex' +import EventCreate from './views/Event/EventCreate' +import EventShow from './views/Event/EventShow' +import EventEdit from './views/Event/EventEdit' Vue.use(VueRouter) @@ -66,6 +70,20 @@ export default new VueRouter({ meta: {title: 'Details of List'} }, + { + path: '/events', component: EventIndex, + meta: {title: 'Events List'} + }, { + path: '/events/create', component: EventCreate, + meta: {title: 'Add New Event'} + }, { + path: '/events/:id', component: EventShow, + meta: {title: 'Detail for Event'} + }, { + path: '/events/:id/edit', component: EventEdit, + meta: {title: 'Edit Event'} + }, + { path: '/bookmarks', component: BookmarkIndex, meta: {title: 'Bookmark Lists'} diff --git a/resources/js/views/Bookmark/BookmarkIndex.vue b/resources/js/views/Bookmark/BookmarkIndex.vue index 98f52a8..cdb9e0f 100644 --- a/resources/js/views/Bookmark/BookmarkIndex.vue +++ b/resources/js/views/Bookmark/BookmarkIndex.vue @@ -30,7 +30,7 @@ diff --git a/resources/js/views/Event/EventEdit.vue b/resources/js/views/Event/EventEdit.vue new file mode 100644 index 0000000..d3978ad --- /dev/null +++ b/resources/js/views/Event/EventEdit.vue @@ -0,0 +1,137 @@ + + + + diff --git a/resources/js/views/Event/EventIndex.vue b/resources/js/views/Event/EventIndex.vue new file mode 100644 index 0000000..c82ab4a --- /dev/null +++ b/resources/js/views/Event/EventIndex.vue @@ -0,0 +1,58 @@ + + + diff --git a/resources/js/views/Event/EventShow.vue b/resources/js/views/Event/EventShow.vue new file mode 100644 index 0000000..aa33d6e --- /dev/null +++ b/resources/js/views/Event/EventShow.vue @@ -0,0 +1,77 @@ + + + + diff --git a/resources/js/views/Memo/MemoCreate.vue b/resources/js/views/Memo/MemoCreate.vue index f53603d..b04b105 100755 --- a/resources/js/views/Memo/MemoCreate.vue +++ b/resources/js/views/Memo/MemoCreate.vue @@ -14,8 +14,8 @@