diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..5657f6e --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +vendor \ No newline at end of file diff --git a/.env.testing b/.env.testing new file mode 100644 index 0000000..f817e90 --- /dev/null +++ b/.env.testing @@ -0,0 +1,49 @@ +APP_NAME=Laravel +APP_ENV=local +APP_KEY=base64:k/nD/nGycrB8CR2Xuu1svePLBI4YT8mBR7TbmZznigI= +APP_DEBUG=false +APP_URL=http://localhost + +LOG_CHANNEL=stack +LOG_DEPRECATIONS_CHANNEL=null +LOG_LEVEL=debug + +DB_CONNECTION=sqlite + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +FILESYSTEM_DRIVER=local +QUEUE_CONNECTION=sync +SESSION_DRIVER=file +SESSION_LIFETIME=120 + +MEMCACHED_HOST=127.0.0.1 + +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_MAILER=smtp +MAIL_HOST=mailhog +MAIL_PORT=1025 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS=null +MAIL_FROM_NAME="${APP_NAME}" + +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= +AWS_USE_PATH_STYLE_ENDPOINT=false + +PUSHER_APP_ID= +PUSHER_APP_KEY= +PUSHER_APP_SECRET= +PUSHER_APP_CLUSTER=mt1 + +MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" + +DB_DATABASE=":memory:" \ No newline at end of file diff --git a/.gitignore b/.gitignore index eb003b0..5d19f90 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ npm-debug.log yarn-error.log /.idea /.vscode +/storage/debugbar \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d8e7995 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,81 @@ +FROM php:8.0-fpm + +# Set working directory +WORKDIR /var/www + +# Install dependencies +RUN apt-get update && apt-get install -y \ + libmemcached-dev \ + wget \ + libonig-dev \ + libzip-dev \ + build-essential \ + libpng-dev \ + libjpeg62-turbo-dev \ + libfreetype6-dev \ + locales \ + zip \ + jpegoptim optipng pngquant gifsicle \ + unzip \ + git \ + curl \ + lua-zlib-dev \ + libmemcached-dev \ + nginx \ + redis-server + +# Install php extensions +RUN docker-php-ext-install mbstring pdo_mysql zip exif pcntl gd + +# Install Memcached +RUN mkdir -p /usr/src/php/ext/memcached +WORKDIR /usr/src/php/ext/memcached +RUN wget https://github.com/php-memcached-dev/php-memcached/archive/v3.2.0.zip; unzip /usr/src/php/ext/memcached/v3.2.0.zip +RUN mv /usr/src/php/ext/memcached/php-memcached-3.2.0/* /usr/src/php/ext/memcached/ +RUN docker-php-ext-configure memcached && docker-php-ext-install memcached +# reset working dir +WORKDIR /var/www + + +RUN mkdir -p /usr/src/php/ext/redis +WORKDIR /usr/src/php/ext/redis +RUN curl -fsSL https://pecl.php.net/get/redis --ipv4 | tar xvz -C "/usr/src/php/ext/redis" --strip 1; +RUN docker-php-ext-configure redis && docker-php-ext-install redis +# reset working dir +WORKDIR /var/www + + +# Install supervisor +RUN apt-get install -y supervisor + +# Install composer +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +# Clear cache +RUN apt-get clean && rm -rf /var/lib/apt/lists/* + +# Add user for laravel application +RUN groupadd -g 1000 www +RUN useradd -u 1000 -ms /bin/bash -g www www + +# Copy code to /var/www +COPY --chown=www:www-data . /var/www + +# add root to www group +RUN chmod -R ug+w /var/www/storage + +# Copy nginx/php/supervisor configs +RUN cp docker/supervisor.conf /etc/supervisord.conf +RUN cp docker/php.ini /usr/local/etc/php/conf.d/app.ini +RUN cp docker/nginx.conf /etc/nginx/sites-enabled/default + +# PHP Error Log Files +RUN mkdir /var/log/php +RUN touch /var/log/php/errors.log && chmod 777 /var/log/php/errors.log + +# Deployment steps +RUN composer install --optimize-autoloader --no-dev +RUN chmod +x /var/www/docker/run.sh + +EXPOSE 80 +ENTRYPOINT ["/var/www/docker/run.sh"] diff --git a/Dockerfile.local b/Dockerfile.local new file mode 100644 index 0000000..cba323f --- /dev/null +++ b/Dockerfile.local @@ -0,0 +1,83 @@ +FROM php:8.0-fpm + +# Set working directory +WORKDIR /var/www + +# Install dependencies +RUN apt-get update && apt-get install -y \ + libmemcached-dev \ + wget \ + libonig-dev \ + libzip-dev \ + build-essential \ + libpng-dev \ + libjpeg62-turbo-dev \ + libfreetype6-dev \ + locales \ + zip \ + jpegoptim optipng pngquant gifsicle \ + unzip \ + git \ + curl \ + lua-zlib-dev \ + libmemcached-dev \ + nginx \ + redis-server + +# Install php extensions +RUN docker-php-ext-install mbstring pdo_mysql zip exif pcntl gd + +# Install Memcached +RUN mkdir -p /usr/src/php/ext/memcached +WORKDIR /usr/src/php/ext/memcached +RUN wget https://github.com/php-memcached-dev/php-memcached/archive/v3.2.0.zip; unzip /usr/src/php/ext/memcached/v3.2.0.zip +RUN mv /usr/src/php/ext/memcached/php-memcached-3.2.0/* /usr/src/php/ext/memcached/ +RUN docker-php-ext-configure memcached && docker-php-ext-install memcached +# reset working dir +WORKDIR /var/www + + +RUN mkdir -p /usr/src/php/ext/redis +WORKDIR /usr/src/php/ext/redis +RUN curl -fsSL https://pecl.php.net/get/redis --ipv4 | tar xvz -C "/usr/src/php/ext/redis" --strip 1; +RUN docker-php-ext-configure redis && docker-php-ext-install redis +# reset working dir +WORKDIR /var/www + + +# Install supervisor +RUN apt-get install -y supervisor + +# Install composer +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +# Clear cache +RUN apt-get clean && rm -rf /var/lib/apt/lists/* + +# Add user for laravel application +RUN groupadd -g 1000 www +RUN useradd -u 1000 -ms /bin/bash -g www www + +# Copy code to /var/www +COPY --chown=www:www-data . /var/www + +# add root to www group +RUN chmod -R ug+w /var/www/storage + +VOLUME . /var/www + +# Copy nginx/php/supervisor configs +RUN cp docker/supervisor.conf /etc/supervisord.conf +RUN cp docker/php.ini /usr/local/etc/php/conf.d/app.ini +RUN cp docker/nginx.conf /etc/nginx/sites-enabled/default + +# PHP Error Log Files +RUN mkdir /var/log/php +RUN touch /var/log/php/errors.log && chmod 777 /var/log/php/errors.log + +# Deployment steps +RUN composer install --optimize-autoloader --no-dev +RUN chmod +x /var/www/docker/run.sh + +EXPOSE 80 +ENTRYPOINT ["/var/www/docker/run.sh"] diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 8e7fbd1..efd2940 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -1,16 +1,23 @@ > + * @var array */ protected $dontReport = [ // @@ -19,23 +26,65 @@ class Handler extends ExceptionHandler /** * A list of the inputs that are never flashed for validation exceptions. * - * @var array + * @var array */ protected $dontFlash = [ - 'current_password', 'password', 'password_confirmation', ]; /** - * Register the exception handling callbacks for the application. + * Report or log an exception. * + * @param Exception $exception * @return void */ - public function register() + public function report(Throwable $exception) + { + if (app()->bound('sentry') && $this->shouldReport($exception)) { + app('sentry')->captureException($exception); + } + parent::report($exception); + } + + /** + * Render an exception into an HTTP response. + * + * @param Request $request + * @param Exception $exception + * @return Response + */ + public function render($request, Throwable $exception) + { + if ($exception instanceof UnauthorizedException) { + return response()->json(["message" => $exception->getMessage()], 403); + } elseif ($exception instanceof ModelNotFoundException) { + return response()->json(['message' => 'Respected model not found'], 422); + } elseif ($exception instanceof NotFoundHttpException) { + return response()->json(['message' => $exception->getMessage()], 404); + } elseif ($request->expectsJson() && $exception instanceof HttpException && $exception->getStatusCode()===503) { + return response()->json(['message' => $exception->getMessage()], 503); + } + + return parent::render($request, $exception); + } + + /** + * Convert a validation exception into a JSON response. + * + * @param Request $request + * @param ValidationException $exception + * @return JsonResponse + */ + protected function invalidJson($request, ValidationException $exception) + { + return response()->json($exception->errors(), $exception->status); + } + protected function convertValidationExceptionToResponse(ValidationException $e, $request) { - $this->reportable(function (Throwable $e) { - // - }); + if ($e->response) { + return $e->response; + } + return $this->invalidJson($request, $e); } -} +} \ No newline at end of file diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php new file mode 100644 index 0000000..68a4862 --- /dev/null +++ b/app/Http/Controllers/ProjectController.php @@ -0,0 +1,96 @@ +middleware([\Spatie\ResponseCache\Middlewares\CacheResponse::class,'acl:list:projects'])->only(['index']); + $this->middleware('acl:create:project')->only(['store']); + $this->middleware('acl:view:project')->only(['show']); + $this->middleware('acl:update:project')->only(['update']); + $this->middleware('acl:delete:project')->only(['destroy']); + } + /** + * Display a listing of the resource. + * + * @return \Illuminate\Http\Response + */ + public function index(Request $request) + { + $query =Project::query(); + if ($request->query('q',null)) { + $query->where('name','like',$request->query('q')); + } + + return $query->jsonPaginate(); + } + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(ProjectRequest $request) + { + $input = $request->input(); + + $project = Project::create([ + 'name' => $input['name'], + ]); + + return new ProjectResource($project); + } + + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + return new ProjectResource(Project::findOrFail($id)); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(ProjectRequest $request, Project $project) + { + $input = $request->input(); + + $project->fill([ + 'name' => $input['name'], + ]); + + return new ProjectResource($project); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy(Project $project) + { + $project->delete(); + + return response()->json([ + 'message' => 'Project deleted successfully' + ], 200); + } +} diff --git a/app/Http/Controllers/TaskController.php b/app/Http/Controllers/TaskController.php new file mode 100644 index 0000000..b022b5e --- /dev/null +++ b/app/Http/Controllers/TaskController.php @@ -0,0 +1,138 @@ +middleware('acl:create:task')->only(['store']); + $this->middleware('acl:delete:task')->only(['destroy']); + } + + /** + Display a listing of the resource. + * + * @return \Illuminate\Http\Response + */ + public function index() + { + $canListAllTasks = $request->user()->tokenCan('list:tasks'); + $canListOwnTasks = $request->user()->tokenCan('list:own:tasks'); + if (!$canListAllTasks && !$canListOwnTasks) { + throw new UnauthorizedException('You are not authorized for this action', 403); + } + if ($canListAllTasks) { + return Task::simplePaginate(10); + } + $userId = $request->user()->id; + return Task::where(['user_id' => $userId])->simplePaginate(); + } + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(TaskRequest $request) + { + $input = $request->input(); + + $task = Task::create([ + 'title' => $input['title'], + 'description' => $input['description'], + 'status' => $input['status'], + 'project_id' => $input['project_id'], + 'user_id' => $input['user_id'], + ]); + + return new TaskResource($task); + } + + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + $canViewTask = $request->user()->tokenCan('view:task'); + $canViewOwnTask = $request->user()->tokenCan('view:own:task'); + if (!$canViewTask && !$canViewOwnTask) { + throw new UnauthorizedException('You are not authorized for this action', 403); + } + if ( + !$canViewTask + && $canViewOwnTask + && $task->user_id !== $request->user->id + ) { + throw new UnauthorizedException('You are not authorized for this action', 403); + } + + return $task->toArray(); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(TaskRequest $request, $taskId) + { + + $canUpdateTask = $request->user()->tokenCan('update:task'); + $canUpdateOwnTask = $request->user()->tokenCan('update:own:task'); + if (!$canUpdateTask && !$canUpdateOwnTask) { + throw new UnauthorizedException('You are not authorized for this action', 403); + } + $task = Task::findOrFail($taskId); + + if ( + !$canUpdateTask + && $canUpdateOwnTask + && $task->user_id !== $request->user->id + ) { + throw new UnauthorizedException('You are not authorized for this action', 403); + } + $updatable = [ + 'title', + 'description', + 'status', + 'project_id', + ]; + // A user cannot assign the task to another member + // Only product owner can + if ($canUpdateTask) { + array_push($updatable, 'user_id'); + } + $taskData = $request->only($updatable); + $task->update($taskData); + return $task->toArray(); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy(Task $task) + { + $task->delete(); + + return response()->json([ + 'message' => 'Task deleted successfully' + ], 200); + } +} diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php new file mode 100644 index 0000000..8c76dad --- /dev/null +++ b/app/Http/Controllers/UserController.php @@ -0,0 +1,107 @@ +middleware('acl:list:users')->only(['index']); + $this->middleware('acl:create:user')->only(['store']); + $this->middleware('acl:view:user')->only(['show']); + $this->middleware('acl:update:user')->only(['update']); + $this->middleware('acl:delete:user')->only(['destroy']); + } + /** + * Display a listing of the resource. + * + * @return \Illuminate\Http\Response + */ + public function index() + { + return UserResource::collection(User::all()); + } + + /** + * Store a newly created resource in storage. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(UserRequest $request) + { + + $user = app('user_manager')->store($request->input()); + + return new UserResource($user); + } + + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + return new UserResource(User::findOrFail($id)); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(UserRequest $request, $userId) + { + $user = User::findOrFail($userId); + $user = app('user_manager')->store($request->input(), $user); + + + return new UserResource($user); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($userId) + { + $user = User::findOrFail($userId); + + $user->delete(); + + return response()->json([ + 'message' => 'User deleted successfully' + ], 200); + } + + public function login(Request $request) { + if( + Auth::attempt([ + 'username' => $request->username, + 'password' => $request->password + ]) + ) { + $role = Auth::user()->role->slug; + $token = $request->user()->createToken($request->username, config("acl.{$role}") ?? []); + return [ + 'token' => $token->plainTextToken + ]; + } + throw new NotFoundHttpException('Cannot find user with provided details'); + } +} \ No newline at end of file diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index d3722c2..caf2353 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -40,7 +40,7 @@ class Kernel extends HttpKernel ], 'api' => [ - // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, + \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], @@ -63,5 +63,10 @@ class Kernel extends HttpKernel 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + 'abilities' => \Laravel\Sanctum\Http\Middleware\CheckAbilities::class, + 'ability' => \Laravel\Sanctum\Http\Middleware\CheckForAnyAbility::class, + 'acl' => \App\Http\Middleware\Acl::class, + 'doNotCacheResponse' => \Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class, + ]; } diff --git a/app/Http/Middleware/Acl.php b/app/Http/Middleware/Acl.php new file mode 100644 index 0000000..c7812a8 --- /dev/null +++ b/app/Http/Middleware/Acl.php @@ -0,0 +1,25 @@ +user()->tokenCan($ability)) { + throw new UnauthorizedException('You are not authorized'); + } + return $next($request); + } +} diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 9e86521..a58f6cd 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -12,6 +12,6 @@ class VerifyCsrfToken extends Middleware * @var array */ protected $except = [ - // + 'api/v1/*' ]; } diff --git a/app/Http/Requests/ProjectRequest.php b/app/Http/Requests/ProjectRequest.php new file mode 100644 index 0000000..69dae56 --- /dev/null +++ b/app/Http/Requests/ProjectRequest.php @@ -0,0 +1,50 @@ + __("Name")]); + $messages['name.string'] = __("The :name field must be a string", ["name" => __("Name")]); + $messages['nmae.unique'] = __("The :name has already been taken", ["name" => __("Name")]); + + return $messages; + + } +} \ No newline at end of file diff --git a/app/Http/Requests/TaskRequest.php b/app/Http/Requests/TaskRequest.php new file mode 100644 index 0000000..382b650 --- /dev/null +++ b/app/Http/Requests/TaskRequest.php @@ -0,0 +1,70 @@ +isMethod('put') || $this->isMethod('patch')) { + foreach($rules as $key=>$rule) { + array_unshift($rule,'sometimes'); + $rules[$key]=$rule; + } + } + + return $rules; + } + + /** + * Get the error messages for the defined validation rules. + * + * @return array + */ + public function messages() + { + + $messages = []; + + $messages['title.required'] = __("The :name field is required", ["name" => __("Title")]); + $messages['title.string'] = __("The :name field must be a string", ["name" => __("Title")]); + + $messages['description.string'] = __("The :name field must be a string", ["name" => __("Description")]); + + $messages['status.required'] = __("The :name field is required", ["name" => __("Status")]); + $messages['status.string'] = __("The :name field must be a string", ["name" => __("Status")]); + + $messages['project_id.required'] = __("The :name field is required", ["name" => __("Project ID")]); + $messages['project_id.exists'] = __("The :name not exist", ["name" => __("Project ID")]); + + $messages['user_id.required'] = __("The :name field is required", ["name" => __("user ID")]); + $messages['user_id.exists'] = __("The :name not exist", ["name" => __("User ID")]); + + return $messages; + + } +} \ No newline at end of file diff --git a/app/Http/Requests/UserRequest.php b/app/Http/Requests/UserRequest.php new file mode 100644 index 0000000..c87baed --- /dev/null +++ b/app/Http/Requests/UserRequest.php @@ -0,0 +1,69 @@ +isMethod('put') || $this->isMethod('patch')) { + foreach($rules as $key=>$rule) { + array_unshift($rule,'sometimes'); + $rules[$key]=$rule; + } + } + return $rules; + } + + /** + * Get the error messages for the defined validation rules. + * + * @return array + */ + public function messages() + { + + $messages = []; + + $messages['email.required'] = __("The :name field is required", ["name" => __("Email")]); + $messages['email.unique'] = __("The :name has already been taken", ["name" => __("Email")]); + + $messages['username.required'] = __("The :name field is required", ["name" => __("Username")]); + $messages['username.min:3'] = __("The :name field must contain at least 3 character", ["name" => __("Username")]); + $messages['username.max:255'] = __("The :name field cannot exceed 255 character", ["name" => __("Username")]); + $messages['username.unique:users,username'] = __("The :name has already been taken", ["name" => __("Username")]); + + $messages['password.required'] = __("The :name field is required", ["name" => __("Password")]); + $messages['password.min:6'] = __("The :name must contain at least 6 character", ["name" => __("Password")]); + + $messages['role_id.required'] = __("The :name field is required", ["name" => __("Role")]); + $messages['role_id.exists'] = __("The :name not exist", ["name" => __("Role")]); + + return $messages; + + } +} \ No newline at end of file diff --git a/app/Managers/UserManager.php b/app/Managers/UserManager.php new file mode 100644 index 0000000..4a49a1c --- /dev/null +++ b/app/Managers/UserManager.php @@ -0,0 +1,41 @@ + $input['email'], + 'username' => $input['username'], + 'name' => $input['name'], + 'role_id' => $input['role_id'], + ]); + } else { + $fillables = ['email','name','username','role_id']; + foreach ($fillables as $key => $value) { + if (isset($input[$value])) { + $user->fill([ + $value => $input[$value] + ]); + } + } + + + } + if (isset($input['password'])) { + $user->password = Hash::make($input['password']); + } + $user->save(); + return $user; + } +} \ No newline at end of file diff --git a/app/Models/ClearCacheTrait.php b/app/Models/ClearCacheTrait.php new file mode 100644 index 0000000..153ca02 --- /dev/null +++ b/app/Models/ClearCacheTrait.php @@ -0,0 +1,22 @@ + + */ + protected $fillable = [ + 'id', + 'name', + ]; + + public function task(){ + return $this->hasMany(Task::class, 'project_id', 'id'); + } +} diff --git a/app/Models/Role.php b/app/Models/Role.php new file mode 100644 index 0000000..b3a93ae --- /dev/null +++ b/app/Models/Role.php @@ -0,0 +1,35 @@ + "Admin", + "PRODUCT_OWNER" => "Product Owner", + "TEAM_MEMBER" => "Team Member" + ]; + const ADMIN ='ADMIN'; + const PRODUCT_OWNER ='PRODUCT_OWNER'; + const TEAM_MEMBER ='TEAM_MEMBER'; + + public static function scopeIsAdmin($query) + { + return $query->where('slug',static::ADMIN); + } + public static function scopeIsProductOwner($query) + { + return $query->where('slug',static::PRODUCT_OWNER); + } + public static function scopeIsTeamMember($query) + { + return $query->where('slug',static::TEAM_MEMBER); + } +} diff --git a/app/Models/Task.php b/app/Models/Task.php new file mode 100644 index 0000000..24d003a --- /dev/null +++ b/app/Models/Task.php @@ -0,0 +1,43 @@ + "NOT_STARTED", + "IN_PROGRESS" => "IN_PROGRESS", + "READY_FOR_TEST" => "READY_FOR_TEST", + "COMPLETED" => "COMPLETED", + ); + + /** + * The attributes that are mass assignable. + * + * @var array + */ + protected $fillable = [ + 'id', + 'title', + 'description', + 'status', + 'project_id', + 'user_id', + ]; + + public function project(){ + return $this->hasOne(Project::class, 'id', 'project_id'); + } + + public function user(){ + return $this->hasOne(User::class, 'id', 'user_id'); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index 8996368..6868b9d 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -4,23 +4,40 @@ use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; -use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Sanctum\HasApiTokens; +use GoldSpecDigital\LaravelEloquentUUID\Foundation\Auth\User as Authenticatable; +/** + * + * @OA\Schema(schema="Login", + * @OA\Property(property="username", type="string", description="username", default="admin"), + * @OA\Property(property="password", type="string", description="password", default="admin@123") + * ); + * @OA\RequestBody( + * request="Login", + * description="Login ", + * required=true, + * @OA\JsonContent(ref="#/components/schemas/Login") + * ) + **/ class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable; + public $incrementing = false; + /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ - 'name', + 'id', + 'username', 'email', - 'password', + 'name', + 'role_id' ]; /** @@ -41,4 +58,12 @@ class User extends Authenticatable protected $casts = [ 'email_verified_at' => 'datetime', ]; + + public function task(){ + return $this->hasMany(Task::class, 'user_id', 'id'); + } + + public function role(){ + return $this->hasOne(Role::class, 'id', 'role_id'); + } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index ee8ca5b..ac5111e 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -3,6 +3,7 @@ namespace App\Providers; use Illuminate\Support\ServiceProvider; +use App\Managers\UserManager; class AppServiceProvider extends ServiceProvider { @@ -13,7 +14,10 @@ class AppServiceProvider extends ServiceProvider */ public function register() { - // + $this->app->singleton('user_manager', function($app) { + return new UserManager(); + }); + } /** diff --git a/app/Resources/ProjectResource.php b/app/Resources/ProjectResource.php new file mode 100644 index 0000000..427622e --- /dev/null +++ b/app/Resources/ProjectResource.php @@ -0,0 +1,30 @@ + $this->id, + 'name' => $this->name, + ]; + + } +} \ No newline at end of file diff --git a/app/Resources/TaskResource.php b/app/Resources/TaskResource.php new file mode 100644 index 0000000..c5e3631 --- /dev/null +++ b/app/Resources/TaskResource.php @@ -0,0 +1,34 @@ + $this->id, + 'title' => $this->title, + 'description' => $this->description, + 'status' => $this->status, + 'project_id' => $this->project_id, + 'user_id' => $this->user_id, + ]; + + } +} \ No newline at end of file diff --git a/app/Resources/UserResource.php b/app/Resources/UserResource.php new file mode 100644 index 0000000..f242b23 --- /dev/null +++ b/app/Resources/UserResource.php @@ -0,0 +1,43 @@ + $this->id, + 'email' => $this->email, + 'username' => $this->username, + 'name' => $this->name, + 'role_id' => $this->role_id, + 'role'=>$this->role->name, + ]; + + } +} \ No newline at end of file diff --git a/app/api.php b/app/api.php new file mode 100644 index 0000000..3e7c8eb --- /dev/null +++ b/app/api.php @@ -0,0 +1,165 @@ +=8.40.0 || ^7.0", + "php": "^7.2 || ^8.0", + "swagger-api/swagger-ui": "^3.0", + "symfony/yaml": "^5.0", + "zircote/swagger-php": "3.*" + }, + "require-dev": { + "mockery/mockery": "1.*", + "orchestra/testbench": "6.* || 5.*", + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "9.*" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "L5Swagger\\L5SwaggerServiceProvider" + ], + "aliases": { + "L5Swagger": "L5Swagger\\L5SwaggerFacade" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "L5Swagger\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Darius Matulionis", + "email": "darius@matulionis.lt" + } + ], + "description": "OpenApi or Swagger integration to Laravel", + "keywords": [ + "api", + "documentation", + "laravel", + "openapi", + "specification", + "swagger", + "ui" + ], + "support": { + "issues": "https://github.com/DarkaOnLine/L5-Swagger/issues", + "source": "https://github.com/DarkaOnLine/L5-Swagger/tree/8.1.0" + }, + "funding": [ + { + "url": "https://github.com/DarkaOnLine", + "type": "github" + } + ], + "time": "2022-01-07T09:08:44+00:00" + }, { "name": "dflydev/dot-access-data", "version": "v3.0.1", @@ -141,6 +276,79 @@ }, "time": "2021-08-13T13:06:58+00:00" }, + { + "name": "doctrine/annotations", + "version": "1.13.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "648b0343343565c4a056bfc8392201385e8d89f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/648b0343343565c4a056bfc8392201385e8d89f0", + "reference": "648b0343343565c4a056bfc8392201385e8d89f0", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0", + "psr/cache": "^1 || ^2 || ^3" + }, + "require-dev": { + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/coding-standard": "^6.0 || ^8.1", + "phpstan/phpstan": "^1.4.10 || ^1.8.0", + "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", + "symfony/cache": "^4.4 || ^5.2", + "vimeo/psalm": "^4.10" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/1.13.3" + }, + "time": "2022-07-02T10:48:51+00:00" + }, { "name": "doctrine/inflector", "version": "2.0.4", @@ -234,16 +442,16 @@ }, { "name": "doctrine/lexer", - "version": "1.2.2", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c" + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c", - "reference": "9c50f840f257bbb941e6f4a0e94ccf5db5c3f76c", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229", "shasum": "" }, "require": { @@ -251,7 +459,7 @@ }, "require-dev": { "doctrine/coding-standard": "^9.0", - "phpstan/phpstan": "1.3", + "phpstan/phpstan": "^1.3", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", "vimeo/psalm": "^4.11" }, @@ -290,7 +498,7 @@ ], "support": { "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/1.2.2" + "source": "https://github.com/doctrine/lexer/tree/1.2.3" }, "funding": [ { @@ -306,7 +514,7 @@ "type": "tidelift" } ], - "time": "2022-01-12T08:27:12+00:00" + "time": "2022-02-28T11:07:21+00:00" }, { "name": "dragonmantank/cron-expression", @@ -439,20 +647,20 @@ }, { "name": "fruitcake/laravel-cors", - "version": "v2.1.0", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/fruitcake/laravel-cors.git", - "reference": "361d71f00a0eea8b74da26ae75d0d207c53aa5b3" + "reference": "783a74f5e3431d7b9805be8afb60fd0a8f743534" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fruitcake/laravel-cors/zipball/361d71f00a0eea8b74da26ae75d0d207c53aa5b3", - "reference": "361d71f00a0eea8b74da26ae75d0d207c53aa5b3", + "url": "https://api.github.com/repos/fruitcake/laravel-cors/zipball/783a74f5e3431d7b9805be8afb60fd0a8f743534", + "reference": "783a74f5e3431d7b9805be8afb60fd0a8f743534", "shasum": "" }, "require": { - "fruitcake/php-cors": "^1", + "asm89/stack-cors": "^2.0.1", "illuminate/contracts": "^6|^7|^8|^9", "illuminate/support": "^6|^7|^8|^9", "php": ">=7.2" @@ -502,7 +710,7 @@ ], "support": { "issues": "https://github.com/fruitcake/laravel-cors/issues", - "source": "https://github.com/fruitcake/laravel-cors/tree/v2.1.0" + "source": "https://github.com/fruitcake/laravel-cors/tree/v2.2.0" }, "funding": [ { @@ -514,40 +722,42 @@ "type": "github" } ], - "time": "2022-02-19T14:17:28+00:00" + "time": "2022-02-23T14:25:13+00:00" }, { - "name": "fruitcake/php-cors", - "version": "v1.2.0", + "name": "goldspecdigital/laravel-eloquent-uuid", + "version": "v8.0.1", "source": { "type": "git", - "url": "https://github.com/fruitcake/php-cors.git", - "reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e" + "url": "https://github.com/goldspecdigital/laravel-eloquent-uuid.git", + "reference": "e98748113e3b9de5b408cdc306e9d93e18121988" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/58571acbaa5f9f462c9c77e911700ac66f446d4e", - "reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e", + "url": "https://api.github.com/repos/goldspecdigital/laravel-eloquent-uuid/zipball/e98748113e3b9de5b408cdc306e9d93e18121988", + "reference": "e98748113e3b9de5b408cdc306e9d93e18121988", "shasum": "" }, "require": { - "php": "^7.4|^8.0", - "symfony/http-foundation": "^4.4|^5.4|^6" + "laravel/framework": "^8.0", + "php": "^7.3 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1.4", - "phpunit/phpunit": "^9", - "squizlabs/php_codesniffer": "^3.5" + "ext-pdo": "*", + "orchestra/testbench": "^6.0", + "phpunit/phpunit": "^8.4" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.1-dev" + "laravel": { + "providers": [ + "GoldSpecDigital\\LaravelEloquentUUID\\UuidServiceProvider" + ] } }, "autoload": { "psr-4": { - "Fruitcake\\Cors\\": "src/" + "GoldSpecDigital\\LaravelEloquentUUID\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -556,57 +766,44 @@ ], "authors": [ { - "name": "Fruitcake", - "homepage": "https://fruitcake.nl" - }, - { - "name": "Barryvdh", - "email": "barryvdh@gmail.com" + "name": "Matthew Inamdar", + "email": "matt@goldspecdigital.com" } ], - "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", - "homepage": "https://github.com/fruitcake/php-cors", + "description": "A simple drop-in solution for providing UUID support for the IDs of your Eloquent models.", + "homepage": "https://github.com/goldspecdigital/laravel-eloquent-uuid", "keywords": [ - "cors", + "eloquent", "laravel", - "symfony" + "php", + "uuid" ], "support": { - "issues": "https://github.com/fruitcake/php-cors/issues", - "source": "https://github.com/fruitcake/php-cors/tree/v1.2.0" + "issues": "https://github.com/goldspecdigital/laravel-eloquent-uuid/issues", + "source": "https://github.com/goldspecdigital/laravel-eloquent-uuid/tree/v8.0.1" }, - "funding": [ - { - "url": "https://fruitcake.nl", - "type": "custom" - }, - { - "url": "https://github.com/barryvdh", - "type": "github" - } - ], - "time": "2022-02-20T15:07:15+00:00" + "time": "2020-12-23T10:10:54+00:00" }, { "name": "graham-campbell/result-type", - "version": "v1.0.4", + "version": "v1.1.0", "source": { "type": "git", "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "0690bde05318336c7221785f2a932467f98b64ca" + "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/0690bde05318336c7221785f2a932467f98b64ca", - "reference": "0690bde05318336c7221785f2a932467f98b64ca", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/a878d45c1914464426dc94da61c9e1d36ae262a8", + "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8", "shasum": "" }, "require": { - "php": "^7.0 || ^8.0", - "phpoption/phpoption": "^1.8" + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9" }, "require-dev": { - "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" + "phpunit/phpunit": "^8.5.28 || ^9.5.21" }, "type": "library", "autoload": { @@ -635,7 +832,7 @@ ], "support": { "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.0.4" + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.0" }, "funding": [ { @@ -647,26 +844,26 @@ "type": "tidelift" } ], - "time": "2021-11-21T21:41:47+00:00" + "time": "2022-07-30T15:56:11+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "7.4.1", + "version": "7.4.5", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79" + "reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ee0a041b1760e6a53d2a39c8c34115adc2af2c79", - "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/1dd98b0564cb3f6bd16ce683cb755f94c10fbd82", + "reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82", "shasum": "" }, "require": { "ext-json": "*", "guzzlehttp/promises": "^1.5", - "guzzlehttp/psr7": "^1.8.3 || ^2.1", + "guzzlehttp/psr7": "^1.9 || ^2.4", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -755,7 +952,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.4.1" + "source": "https://github.com/guzzle/guzzle/tree/7.4.5" }, "funding": [ { @@ -771,7 +968,7 @@ "type": "tidelift" } ], - "time": "2021-12-06T18:43:05+00:00" + "time": "2022-06-20T22:16:13+00:00" }, { "name": "guzzlehttp/promises", @@ -800,12 +997,12 @@ } }, "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, "files": [ "src/functions_include.php" - ] + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -859,16 +1056,16 @@ }, { "name": "guzzlehttp/psr7", - "version": "2.1.0", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "089edd38f5b8abba6cb01567c2a8aaa47cec4c72" + "reference": "13388f00956b1503577598873fffb5ae994b5737" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/089edd38f5b8abba6cb01567c2a8aaa47cec4c72", - "reference": "089edd38f5b8abba6cb01567c2a8aaa47cec4c72", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/13388f00956b1503577598873fffb5ae994b5737", + "reference": "13388f00956b1503577598873fffb5ae994b5737", "shasum": "" }, "require": { @@ -892,7 +1089,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.4-dev" } }, "autoload": { @@ -954,7 +1151,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.1.0" + "source": "https://github.com/guzzle/psr7/tree/2.4.0" }, "funding": [ { @@ -970,20 +1167,20 @@ "type": "tidelift" } ], - "time": "2021-10-06T17:43:30+00:00" + "time": "2022-06-20T21:43:11+00:00" }, { "name": "laravel/framework", - "version": "v8.83.1", + "version": "v8.83.23", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "bddba117f8bce2f3c9875ca1ca375a96350d0f4d" + "reference": "bdc707f8b9bcad289b24cd182d98ec7480ac4491" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/bddba117f8bce2f3c9875ca1ca375a96350d0f4d", - "reference": "bddba117f8bce2f3c9875ca1ca375a96350d0f4d", + "url": "https://api.github.com/repos/laravel/framework/zipball/bdc707f8b9bcad289b24cd182d98ec7480ac4491", + "reference": "bdc707f8b9bcad289b24cd182d98ec7480ac4491", "shasum": "" }, "require": { @@ -1143,24 +1340,25 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-02-15T15:05:20+00:00" + "time": "2022-07-26T13:30:00+00:00" }, { "name": "laravel/sanctum", - "version": "v2.14.1", + "version": "v2.15.1", "source": { "type": "git", "url": "https://github.com/laravel/sanctum.git", - "reference": "89937617fa144ddb759a740861a47c4f2fd2245b" + "reference": "31fbe6f85aee080c4dc2f9b03dc6dd5d0ee72473" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sanctum/zipball/89937617fa144ddb759a740861a47c4f2fd2245b", - "reference": "89937617fa144ddb759a740861a47c4f2fd2245b", + "url": "https://api.github.com/repos/laravel/sanctum/zipball/31fbe6f85aee080c4dc2f9b03dc6dd5d0ee72473", + "reference": "31fbe6f85aee080c4dc2f9b03dc6dd5d0ee72473", "shasum": "" }, "require": { "ext-json": "*", + "illuminate/console": "^6.9|^7.0|^8.0|^9.0", "illuminate/contracts": "^6.9|^7.0|^8.0|^9.0", "illuminate/database": "^6.9|^7.0|^8.0|^9.0", "illuminate/support": "^6.9|^7.0|^8.0|^9.0", @@ -1207,20 +1405,20 @@ "issues": "https://github.com/laravel/sanctum/issues", "source": "https://github.com/laravel/sanctum" }, - "time": "2022-02-15T08:08:57+00:00" + "time": "2022-04-08T13:39:49+00:00" }, { "name": "laravel/serializable-closure", - "version": "v1.1.1", + "version": "v1.2.0", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "9e4b005daa20b0c161f3845040046dc9ddc1d74e" + "reference": "09f0e9fb61829f628205b7c94906c28740ff9540" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/9e4b005daa20b0c161f3845040046dc9ddc1d74e", - "reference": "9e4b005daa20b0c161f3845040046dc9ddc1d74e", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/09f0e9fb61829f628205b7c94906c28740ff9540", + "reference": "09f0e9fb61829f628205b7c94906c28740ff9540", "shasum": "" }, "require": { @@ -1266,20 +1464,20 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2022-02-11T19:23:53+00:00" + "time": "2022-05-16T17:09:47+00:00" }, { "name": "laravel/tinker", - "version": "v2.7.0", + "version": "v2.7.2", "source": { "type": "git", "url": "https://github.com/laravel/tinker.git", - "reference": "5f2f9815b7631b9f586a3de7933c25f9327d4073" + "reference": "dff39b661e827dae6e092412f976658df82dbac5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/5f2f9815b7631b9f586a3de7933c25f9327d4073", - "reference": "5f2f9815b7631b9f586a3de7933c25f9327d4073", + "url": "https://api.github.com/repos/laravel/tinker/zipball/dff39b661e827dae6e092412f976658df82dbac5", + "reference": "dff39b661e827dae6e092412f976658df82dbac5", "shasum": "" }, "require": { @@ -1332,22 +1530,22 @@ ], "support": { "issues": "https://github.com/laravel/tinker/issues", - "source": "https://github.com/laravel/tinker/tree/v2.7.0" + "source": "https://github.com/laravel/tinker/tree/v2.7.2" }, - "time": "2022-01-10T08:52:49+00:00" + "time": "2022-03-23T12:38:24+00:00" }, { "name": "league/commonmark", - "version": "2.2.2", + "version": "2.3.5", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "13d7751377732637814f0cda0e3f6d3243f9f769" + "reference": "84d74485fdb7074f4f9dd6f02ab957b1de513257" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/13d7751377732637814f0cda0e3f6d3243f9f769", - "reference": "13d7751377732637814f0cda0e3f6d3243f9f769", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/84d74485fdb7074f4f9dd6f02ab957b1de513257", + "reference": "84d74485fdb7074f4f9dd6f02ab957b1de513257", "shasum": "" }, "require": { @@ -1356,24 +1554,26 @@ "php": "^7.4 || ^8.0", "psr/event-dispatcher": "^1.0", "symfony/deprecation-contracts": "^2.1 || ^3.0", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "require-dev": { "cebe/markdown": "^1.0", "commonmark/cmark": "0.30.0", "commonmark/commonmark.js": "0.30.0", "composer/package-versions-deprecated": "^1.8", + "embed/embed": "^4.4", "erusev/parsedown": "^1.0", "ext-json": "*", "github/gfm": "0.29.0", "michelf/php-markdown": "^1.4", - "phpstan/phpstan": "^0.12.88 || ^1.0.0", - "phpunit/phpunit": "^9.5.5", + "nyholm/psr7": "^1.5", + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.21", "scrutinizer/ocular": "^1.8.1", - "symfony/finder": "^5.3", + "symfony/finder": "^5.3 | ^6.0", "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0", - "unleashedtech/php-coding-standard": "^3.1", - "vimeo/psalm": "^4.7.3" + "unleashedtech/php-coding-standard": "^3.1.1", + "vimeo/psalm": "^4.24.0" }, "suggest": { "symfony/yaml": "v2.3+ required if using the Front Matter extension" @@ -1381,7 +1581,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.3-dev" + "dev-main": "2.4-dev" } }, "autoload": { @@ -1438,7 +1638,7 @@ "type": "tidelift" } ], - "time": "2022-02-13T15:00:57+00:00" + "time": "2022-07-29T10:59:45+00:00" }, { "name": "league/config", @@ -1618,16 +1818,16 @@ }, { "name": "league/mime-type-detection", - "version": "1.9.0", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69" + "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/aa70e813a6ad3d1558fc927863d47309b4c23e69", - "reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd", + "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd", "shasum": "" }, "require": { @@ -1658,7 +1858,7 @@ "description": "Mime-type detection for Flysystem", "support": { "issues": "https://github.com/thephpleague/mime-type-detection/issues", - "source": "https://github.com/thephpleague/mime-type-detection/tree/1.9.0" + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0" }, "funding": [ { @@ -1670,20 +1870,20 @@ "type": "tidelift" } ], - "time": "2021-11-21T11:48:40+00:00" + "time": "2022-04-17T13:12:02+00:00" }, { "name": "monolog/monolog", - "version": "2.3.5", + "version": "2.8.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "fd4380d6fc37626e2f799f29d91195040137eba9" + "reference": "720488632c590286b88b80e62aa3d3d551ad4a50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd4380d6fc37626e2f799f29d91195040137eba9", - "reference": "fd4380d6fc37626e2f799f29d91195040137eba9", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/720488632c590286b88b80e62aa3d3d551ad4a50", + "reference": "720488632c590286b88b80e62aa3d3d551ad4a50", "shasum": "" }, "require": { @@ -1696,18 +1896,22 @@ "require-dev": { "aws/aws-sdk-php": "^2.4.9 || ^3.0", "doctrine/couchdb": "~1.0@dev", - "elasticsearch/elasticsearch": "^7", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", "graylog2/gelf-php": "^1.4.2", + "guzzlehttp/guzzle": "^7.4", + "guzzlehttp/psr7": "^2.2", "mongodb/mongodb": "^1.8", "php-amqplib/php-amqplib": "~2.4 || ^3", - "php-console/php-console": "^3.1.3", - "phpspec/prophecy": "^1.6.1", + "phpspec/prophecy": "^1.15", "phpstan/phpstan": "^0.12.91", - "phpunit/phpunit": "^8.5", - "predis/predis": "^1.1", - "rollbar/rollbar": "^1.3", - "ruflin/elastica": ">=0.90@dev", - "swiftmailer/swiftmailer": "^5.3|^6.0" + "phpunit/phpunit": "^8.5.14", + "predis/predis": "^1.1 || ^2.0", + "rollbar/rollbar": "^1.3 || ^2 || ^3", + "ruflin/elastica": "^7", + "swiftmailer/swiftmailer": "^5.3|^6.0", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" }, "suggest": { "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", @@ -1722,7 +1926,6 @@ "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", - "php-console/php-console": "Allow sending log messages to Google Chrome", "rollbar/rollbar": "Allow sending log messages to Rollbar", "ruflin/elastica": "Allow sending log messages to an Elastic Search server" }, @@ -1757,7 +1960,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/2.3.5" + "source": "https://github.com/Seldaek/monolog/tree/2.8.0" }, "funding": [ { @@ -1769,20 +1972,20 @@ "type": "tidelift" } ], - "time": "2021-10-01T21:08:31+00:00" + "time": "2022-07-24T11:55:47+00:00" }, { "name": "nesbot/carbon", - "version": "2.57.0", + "version": "2.61.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "4a54375c21eea4811dbd1149fe6b246517554e78" + "reference": "bdf4f4fe3a3eac4de84dbec0738082a862c68ba6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4a54375c21eea4811dbd1149fe6b246517554e78", - "reference": "4a54375c21eea4811dbd1149fe6b246517554e78", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/bdf4f4fe3a3eac4de84dbec0738082a862c68ba6", + "reference": "bdf4f4fe3a3eac4de84dbec0738082a862c68ba6", "shasum": "" }, "require": { @@ -1797,10 +2000,12 @@ "doctrine/orm": "^2.7", "friendsofphp/php-cs-fixer": "^3.0", "kylekatarnls/multi-tester": "^2.0", + "ondrejmirtes/better-reflection": "*", "phpmd/phpmd": "^2.9", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12.54 || ^1.0", - "phpunit/phpunit": "^7.5.20 || ^8.5.14", + "phpstan/phpstan": "^0.12.99 || ^1.7.14", + "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", + "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", "squizlabs/php_codesniffer": "^3.4" }, "bin": [ @@ -1857,15 +2062,19 @@ }, "funding": [ { - "url": "https://opencollective.com/Carbon", - "type": "open_collective" + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" }, { - "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", "type": "tidelift" } ], - "time": "2022-02-13T18:13:33+00:00" + "time": "2022-08-06T12:41:24+00:00" }, { "name": "nette/schema", @@ -2016,16 +2225,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.13.2", + "version": "v4.14.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077" + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", "shasum": "" }, "require": { @@ -2066,9 +2275,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" }, - "time": "2021-11-30T19:35:32+00:00" + "time": "2022-05-31T20:59:12+00:00" }, { "name": "opis/closure", @@ -2098,12 +2307,12 @@ } }, "autoload": { - "psr-4": { - "Opis\\Closure\\": "src/" - }, "files": [ "functions.php" - ] + ], + "psr-4": { + "Opis\\Closure\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2137,29 +2346,33 @@ }, { "name": "phpoption/phpoption", - "version": "1.8.1", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/schmittjoh/php-option.git", - "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15" + "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15", - "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", + "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", "shasum": "" }, "require": { - "php": "^7.0 || ^8.0" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", - "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" + "bamarni/composer-bin-plugin": "^1.8", + "phpunit/phpunit": "^8.5.28 || ^9.5.21" }, "type": "library", "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, "branch-alias": { - "dev-master": "1.8-dev" + "dev-master": "1.9-dev" } }, "autoload": { @@ -2192,7 +2405,7 @@ ], "support": { "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.8.1" + "source": "https://github.com/schmittjoh/php-option/tree/1.9.0" }, "funding": [ { @@ -2204,7 +2417,56 @@ "type": "tidelift" } ], - "time": "2021-12-04T23:24:31+00:00" + "time": "2022-07-30T15:51:26+00:00" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/master" + }, + "time": "2016-08-06T20:24:11+00:00" }, { "name": "psr/container", @@ -2567,16 +2829,16 @@ }, { "name": "psy/psysh", - "version": "v0.11.1", + "version": "v0.11.8", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "570292577277f06f590635381a7f761a6cf4f026" + "reference": "f455acf3645262ae389b10e9beba0c358aa6994e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/570292577277f06f590635381a7f761a6cf4f026", - "reference": "570292577277f06f590635381a7f761a6cf4f026", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/f455acf3645262ae389b10e9beba0c358aa6994e", + "reference": "f455acf3645262ae389b10e9beba0c358aa6994e", "shasum": "" }, "require": { @@ -2587,16 +2849,17 @@ "symfony/console": "^6.0 || ^5.0 || ^4.0 || ^3.4", "symfony/var-dumper": "^6.0 || ^5.0 || ^4.0 || ^3.4" }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" + }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.2", - "hoa/console": "3.17.05.02" + "bamarni/composer-bin-plugin": "^1.2" }, "suggest": { "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", "ext-pdo-sqlite": "The doc command requires SQLite to work.", "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", - "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history.", - "hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit." + "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history." }, "bin": [ "bin/psysh" @@ -2636,9 +2899,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.11.1" + "source": "https://github.com/bobthecow/psysh/tree/v0.11.8" }, - "time": "2022-01-03T13:58:38+00:00" + "time": "2022-07-28T14:25:11+00:00" }, { "name": "ralouphie/getallheaders", @@ -2828,12 +3091,12 @@ } }, "autoload": { - "psr-4": { - "Ramsey\\Uuid\\": "src/" - }, "files": [ "src/functions.php" - ] + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2861,6 +3124,270 @@ ], "time": "2021-09-25T23:10:38+00:00" }, + { + "name": "spatie/laravel-json-api-paginate", + "version": "1.12.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-json-api-paginate.git", + "reference": "5ecdd3569d07a22798d8fe9de9ec6de640343b75" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-json-api-paginate/zipball/5ecdd3569d07a22798d8fe9de9ec6de640343b75", + "reference": "5ecdd3569d07a22798d8fe9de9ec6de640343b75", + "shasum": "" + }, + "require": { + "illuminate/support": "^6.0|^7.0|^8.0|^9.0", + "php": "^7.3|^8.0" + }, + "require-dev": { + "orchestra/testbench": "^4.0|^5.0|^6.0|^7.0", + "phpunit/phpunit": "^8.0|^9.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\JsonApiPaginate\\JsonApiPaginateServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\JsonApiPaginate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A paginator that plays nice with the JSON API spec", + "homepage": "https://github.com/spatie/laravel-json-api-paginate", + "keywords": [ + "laravel-json-api-paginate", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/laravel-json-api-paginate/tree/1.12.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + } + ], + "time": "2022-05-16T12:16:39+00:00" + }, + { + "name": "spatie/laravel-package-tools", + "version": "1.12.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-package-tools.git", + "reference": "09f80fa240d44fafb1c70657c74ee44ffa929357" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/09f80fa240d44fafb1c70657c74ee44ffa929357", + "reference": "09f80fa240d44fafb1c70657c74ee44ffa929357", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^7.0|^8.0|^9.0", + "php": "^7.4|^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.4", + "orchestra/testbench": "^5.0|^6.23|^7.0", + "phpunit/phpunit": "^9.4", + "spatie/test-time": "^1.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\LaravelPackageTools\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "Tools for creating Laravel packages", + "homepage": "https://github.com/spatie/laravel-package-tools", + "keywords": [ + "laravel-package-tools", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-package-tools/issues", + "source": "https://github.com/spatie/laravel-package-tools/tree/1.12.1" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-06-28T14:29:26+00:00" + }, + { + "name": "spatie/laravel-responsecache", + "version": "6.6.9", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-responsecache.git", + "reference": "cab93fa63fd60e03dc5bb33aef7b45cc014ed6a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-responsecache/zipball/cab93fa63fd60e03dc5bb33aef7b45cc014ed6a3", + "reference": "cab93fa63fd60e03dc5bb33aef7b45cc014ed6a3", + "shasum": "" + }, + "require": { + "illuminate/cache": "^7.13|^8.0", + "illuminate/console": "^7.13|^8.0", + "illuminate/container": "^7.13|^8.0", + "illuminate/http": "^7.13|^8.0", + "illuminate/support": "^7.13|^8.0", + "nesbot/carbon": "^2.35", + "php": "^7.4|^8.0", + "spatie/laravel-package-tools": "^1.1" + }, + "require-dev": { + "laravel/framework": "^7.13|^8.0", + "mockery/mockery": "^1.4", + "orchestra/testbench": "^5.2|^6.0", + "phpunit/phpunit": "^9.1.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\ResponseCache\\ResponseCacheServiceProvider" + ], + "aliases": { + "ResponseCache": "Spatie\\ResponseCache\\Facades\\ResponseCache" + } + } + }, + "autoload": { + "psr-4": { + "Spatie\\ResponseCache\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Speed up a Laravel application by caching the entire response", + "homepage": "https://github.com/spatie/laravel-responsecache", + "keywords": [ + "cache", + "laravel", + "laravel-responsecache", + "performance", + "response", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-responsecache/issues", + "source": "https://github.com/spatie/laravel-responsecache/tree/6.6.9" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + } + ], + "time": "2021-03-30T20:11:33+00:00" + }, + { + "name": "swagger-api/swagger-ui", + "version": "v3.52.5", + "source": { + "type": "git", + "url": "https://github.com/swagger-api/swagger-ui.git", + "reference": "f1ad60dc92e7edb0898583e16c3e66fe3e9eada2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swagger-api/swagger-ui/zipball/f1ad60dc92e7edb0898583e16c3e66fe3e9eada2", + "reference": "f1ad60dc92e7edb0898583e16c3e66fe3e9eada2", + "shasum": "" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Anna Bodnia", + "email": "anna.bodnia@gmail.com" + }, + { + "name": "Buu Nguyen", + "email": "buunguyen@gmail.com" + }, + { + "name": "Josh Ponelat", + "email": "jponelat@gmail.com" + }, + { + "name": "Kyle Shockey", + "email": "kyleshockey1@gmail.com" + }, + { + "name": "Robert Barnwell", + "email": "robert@robertismy.name" + }, + { + "name": "Sahar Jafari", + "email": "shr.jafari@gmail.com" + } + ], + "description": " Swagger UI is a collection of HTML, Javascript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API.", + "homepage": "http://swagger.io", + "keywords": [ + "api", + "documentation", + "openapi", + "specification", + "swagger", + "ui" + ], + "support": { + "issues": "https://github.com/swagger-api/swagger-ui/issues", + "source": "https://github.com/swagger-api/swagger-ui/tree/v3.52.5" + }, + "time": "2021-10-14T14:25:14+00:00" + }, { "name": "swiftmailer/swiftmailer", "version": "v6.3.0", @@ -2939,16 +3466,16 @@ }, { "name": "symfony/console", - "version": "v5.4.3", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "a2a86ec353d825c75856c6fd14fac416a7bdb6b8" + "reference": "535846c7ee6bc4dd027ca0d93220601456734b10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a2a86ec353d825c75856c6fd14fac416a7bdb6b8", - "reference": "a2a86ec353d825c75856c6fd14fac416a7bdb6b8", + "url": "https://api.github.com/repos/symfony/console/zipball/535846c7ee6bc4dd027ca0d93220601456734b10", + "reference": "535846c7ee6bc4dd027ca0d93220601456734b10", "shasum": "" }, "require": { @@ -3018,7 +3545,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.3" + "source": "https://github.com/symfony/console/tree/v5.4.11" }, "funding": [ { @@ -3034,20 +3561,20 @@ "type": "tidelift" } ], - "time": "2022-01-26T16:28:35+00:00" + "time": "2022-07-22T10:42:43+00:00" }, { "name": "symfony/css-selector", - "version": "v5.4.3", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "b0a190285cd95cb019237851205b8140ef6e368e" + "reference": "c1681789f059ab756001052164726ae88512ae3d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/b0a190285cd95cb019237851205b8140ef6e368e", - "reference": "b0a190285cd95cb019237851205b8140ef6e368e", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/c1681789f059ab756001052164726ae88512ae3d", + "reference": "c1681789f059ab756001052164726ae88512ae3d", "shasum": "" }, "require": { @@ -3084,7 +3611,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v5.4.3" + "source": "https://github.com/symfony/css-selector/tree/v5.4.11" }, "funding": [ { @@ -3100,20 +3627,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-06-27T16:58:25+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.0", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", "shasum": "" }, "require": { @@ -3151,7 +3678,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" }, "funding": [ { @@ -3167,20 +3694,20 @@ "type": "tidelift" } ], - "time": "2021-07-12T14:48:14+00:00" + "time": "2022-01-02T09:53:40+00:00" }, { "name": "symfony/error-handler", - "version": "v5.4.3", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "c4ffc2cd919950d13c8c9ce32a70c70214c3ffc5" + "reference": "f75d17cb4769eb38cd5fccbda95cd80a054d35c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/c4ffc2cd919950d13c8c9ce32a70c70214c3ffc5", - "reference": "c4ffc2cd919950d13c8c9ce32a70c70214c3ffc5", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/f75d17cb4769eb38cd5fccbda95cd80a054d35c8", + "reference": "f75d17cb4769eb38cd5fccbda95cd80a054d35c8", "shasum": "" }, "require": { @@ -3222,7 +3749,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v5.4.3" + "source": "https://github.com/symfony/error-handler/tree/v5.4.11" }, "funding": [ { @@ -3238,20 +3765,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-07-29T07:37:50+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.4.3", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "dec8a9f58d20df252b9cd89f1c6c1530f747685d" + "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/dec8a9f58d20df252b9cd89f1c6c1530f747685d", - "reference": "dec8a9f58d20df252b9cd89f1c6c1530f747685d", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", + "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", "shasum": "" }, "require": { @@ -3307,7 +3834,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.3" + "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.9" }, "funding": [ { @@ -3323,20 +3850,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-05-05T16:45:39+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v2.5.0", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a" + "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", - "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/f98b54df6ad059855739db6fcbc2d36995283fe1", + "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1", "shasum": "" }, "require": { @@ -3386,7 +3913,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.2" }, "funding": [ { @@ -3402,20 +3929,20 @@ "type": "tidelift" } ], - "time": "2021-07-12T14:48:14+00:00" + "time": "2022-01-02T09:53:40+00:00" }, { "name": "symfony/finder", - "version": "v5.4.3", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "231313534dded84c7ecaa79d14bc5da4ccb69b7d" + "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/231313534dded84c7ecaa79d14bc5da4ccb69b7d", - "reference": "231313534dded84c7ecaa79d14bc5da4ccb69b7d", + "url": "https://api.github.com/repos/symfony/finder/zipball/7872a66f57caffa2916a584db1aa7f12adc76f8c", + "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c", "shasum": "" }, "require": { @@ -3449,7 +3976,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.3" + "source": "https://github.com/symfony/finder/tree/v5.4.11" }, "funding": [ { @@ -3465,20 +3992,20 @@ "type": "tidelift" } ], - "time": "2022-01-26T16:34:36+00:00" + "time": "2022-07-29T07:37:50+00:00" }, { "name": "symfony/http-foundation", - "version": "v5.4.3", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "ef409ff341a565a3663157d4324536746d49a0c7" + "reference": "0a5868e0999e9d47859ba3d918548ff6943e6389" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ef409ff341a565a3663157d4324536746d49a0c7", - "reference": "ef409ff341a565a3663157d4324536746d49a0c7", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/0a5868e0999e9d47859ba3d918548ff6943e6389", + "reference": "0a5868e0999e9d47859ba3d918548ff6943e6389", "shasum": "" }, "require": { @@ -3522,7 +4049,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.4.3" + "source": "https://github.com/symfony/http-foundation/tree/v5.4.11" }, "funding": [ { @@ -3538,20 +4065,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-07-20T13:00:38+00:00" }, { "name": "symfony/http-kernel", - "version": "v5.4.4", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "49f40347228c773688a0488feea0175aa7f4d268" + "reference": "4fd590a2ef3f62560dbbf6cea511995dd77321ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/49f40347228c773688a0488feea0175aa7f4d268", - "reference": "49f40347228c773688a0488feea0175aa7f4d268", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/4fd590a2ef3f62560dbbf6cea511995dd77321ee", + "reference": "4fd590a2ef3f62560dbbf6cea511995dd77321ee", "shasum": "" }, "require": { @@ -3634,7 +4161,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v5.4.4" + "source": "https://github.com/symfony/http-kernel/tree/v5.4.11" }, "funding": [ { @@ -3650,20 +4177,20 @@ "type": "tidelift" } ], - "time": "2022-01-29T18:08:07+00:00" + "time": "2022-07-29T12:30:22+00:00" }, { "name": "symfony/mime", - "version": "v5.4.3", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "e1503cfb5c9a225350f549d3bb99296f4abfb80f" + "reference": "3cd175cdcdb6db2e589e837dd46aff41027d9830" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/e1503cfb5c9a225350f549d3bb99296f4abfb80f", - "reference": "e1503cfb5c9a225350f549d3bb99296f4abfb80f", + "url": "https://api.github.com/repos/symfony/mime/zipball/3cd175cdcdb6db2e589e837dd46aff41027d9830", + "reference": "3cd175cdcdb6db2e589e837dd46aff41027d9830", "shasum": "" }, "require": { @@ -3717,7 +4244,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.4.3" + "source": "https://github.com/symfony/mime/tree/v5.4.11" }, "funding": [ { @@ -3733,20 +4260,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-07-20T11:34:24+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.24.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "30885182c981ab175d4d034db0f6f469898070ab" + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", - "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", "shasum": "" }, "require": { @@ -3761,7 +4288,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3769,12 +4296,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3799,7 +4326,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" }, "funding": [ { @@ -3815,20 +4342,20 @@ "type": "tidelift" } ], - "time": "2021-10-20T20:35:02+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-iconv", - "version": "v1.24.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "f1aed619e28cb077fc83fac8c4c0383578356e40" + "reference": "143f1881e655bebca1312722af8068de235ae5dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/f1aed619e28cb077fc83fac8c4c0383578356e40", - "reference": "f1aed619e28cb077fc83fac8c4c0383578356e40", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/143f1881e655bebca1312722af8068de235ae5dc", + "reference": "143f1881e655bebca1312722af8068de235ae5dc", "shasum": "" }, "require": { @@ -3843,7 +4370,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3882,7 +4409,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-iconv/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.26.0" }, "funding": [ { @@ -3898,20 +4425,20 @@ "type": "tidelift" } ], - "time": "2022-01-04T09:04:05+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.24.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" + "reference": "433d05519ce6990bf3530fba6957499d327395c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", + "reference": "433d05519ce6990bf3530fba6957499d327395c2", "shasum": "" }, "require": { @@ -3923,7 +4450,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3963,7 +4490,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" }, "funding": [ { @@ -3979,20 +4506,20 @@ "type": "tidelift" } ], - "time": "2021-11-23T21:10:46+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.24.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "749045c69efb97c70d25d7463abba812e91f3a44" + "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/749045c69efb97c70d25d7463abba812e91f3a44", - "reference": "749045c69efb97c70d25d7463abba812e91f3a44", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/59a8d271f00dd0e4c2e518104cc7963f655a1aa8", + "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8", "shasum": "" }, "require": { @@ -4006,7 +4533,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4050,7 +4577,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.26.0" }, "funding": [ { @@ -4066,20 +4593,20 @@ "type": "tidelift" } ], - "time": "2021-09-14T14:02:44+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.24.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + "reference": "219aa369ceff116e673852dce47c3a41794c14bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", + "reference": "219aa369ceff116e673852dce47c3a41794c14bd", "shasum": "" }, "require": { @@ -4091,7 +4618,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4134,7 +4661,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" }, "funding": [ { @@ -4150,20 +4677,20 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.24.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", "shasum": "" }, "require": { @@ -4178,7 +4705,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4217,7 +4744,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" }, "funding": [ { @@ -4233,20 +4760,20 @@ "type": "tidelift" } ], - "time": "2021-11-30T18:21:41+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.24.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" + "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2", + "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2", "shasum": "" }, "require": { @@ -4255,7 +4782,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4293,7 +4820,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0" }, "funding": [ { @@ -4309,20 +4836,20 @@ "type": "tidelift" } ], - "time": "2021-05-27T09:17:38+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.24.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" + "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85", + "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85", "shasum": "" }, "require": { @@ -4331,7 +4858,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4372,7 +4899,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0" }, "funding": [ { @@ -4388,20 +4915,20 @@ "type": "tidelift" } ], - "time": "2021-06-05T21:20:04+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.24.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", "shasum": "" }, "require": { @@ -4410,7 +4937,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4455,7 +4982,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" }, "funding": [ { @@ -4471,20 +4998,20 @@ "type": "tidelift" } ], - "time": "2021-09-13T13:58:33+00:00" + "time": "2022-05-10T07:21:04+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.24.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f" + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", - "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1", "shasum": "" }, "require": { @@ -4493,7 +5020,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4534,7 +5061,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0" }, "funding": [ { @@ -4550,20 +5077,20 @@ "type": "tidelift" } ], - "time": "2021-09-13T13:58:11+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/process", - "version": "v5.4.3", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "553f50487389a977eb31cf6b37faae56da00f753" + "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/553f50487389a977eb31cf6b37faae56da00f753", - "reference": "553f50487389a977eb31cf6b37faae56da00f753", + "url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1", + "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1", "shasum": "" }, "require": { @@ -4596,7 +5123,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.3" + "source": "https://github.com/symfony/process/tree/v5.4.11" }, "funding": [ { @@ -4612,20 +5139,20 @@ "type": "tidelift" } ], - "time": "2022-01-26T16:28:35+00:00" + "time": "2022-06-27T16:58:25+00:00" }, { "name": "symfony/routing", - "version": "v5.4.3", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "44b29c7a94e867ccde1da604792f11a469958981" + "reference": "3e01ccd9b2a3a4167ba2b3c53612762300300226" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/44b29c7a94e867ccde1da604792f11a469958981", - "reference": "44b29c7a94e867ccde1da604792f11a469958981", + "url": "https://api.github.com/repos/symfony/routing/zipball/3e01ccd9b2a3a4167ba2b3c53612762300300226", + "reference": "3e01ccd9b2a3a4167ba2b3c53612762300300226", "shasum": "" }, "require": { @@ -4686,7 +5213,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v5.4.3" + "source": "https://github.com/symfony/routing/tree/v5.4.11" }, "funding": [ { @@ -4702,26 +5229,26 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-07-20T13:00:38+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.5.0", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", "shasum": "" }, "require": { "php": ">=7.2.5", "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1" + "symfony/deprecation-contracts": "^2.1|^3" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -4769,7 +5296,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" }, "funding": [ { @@ -4785,20 +5312,20 @@ "type": "tidelift" } ], - "time": "2021-11-04T16:48:04+00:00" + "time": "2022-05-30T19:17:29+00:00" }, { "name": "symfony/string", - "version": "v5.4.3", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "92043b7d8383e48104e411bc9434b260dbeb5a10" + "reference": "5eb661e49ad389e4ae2b6e4df8d783a8a6548322" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/92043b7d8383e48104e411bc9434b260dbeb5a10", - "reference": "92043b7d8383e48104e411bc9434b260dbeb5a10", + "url": "https://api.github.com/repos/symfony/string/zipball/5eb661e49ad389e4ae2b6e4df8d783a8a6548322", + "reference": "5eb661e49ad389e4ae2b6e4df8d783a8a6548322", "shasum": "" }, "require": { @@ -4820,12 +5347,12 @@ }, "type": "library", "autoload": { - "psr-4": { - "Symfony\\Component\\String\\": "" - }, "files": [ "Resources/functions.php" ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, "exclude-from-classmap": [ "/Tests/" ] @@ -4855,7 +5382,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.3" + "source": "https://github.com/symfony/string/tree/v5.4.11" }, "funding": [ { @@ -4871,20 +5398,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-07-24T16:15:25+00:00" }, { "name": "symfony/translation", - "version": "v5.4.3", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "a9dd7403232c61e87e27fb306bbcd1627f245d70" + "reference": "7a1a8f6bbff269f434a83343a0a5d36a4f8cfa21" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/a9dd7403232c61e87e27fb306bbcd1627f245d70", - "reference": "a9dd7403232c61e87e27fb306bbcd1627f245d70", + "url": "https://api.github.com/repos/symfony/translation/zipball/7a1a8f6bbff269f434a83343a0a5d36a4f8cfa21", + "reference": "7a1a8f6bbff269f434a83343a0a5d36a4f8cfa21", "shasum": "" }, "require": { @@ -4952,7 +5479,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v5.4.3" + "source": "https://github.com/symfony/translation/tree/v5.4.11" }, "funding": [ { @@ -4968,20 +5495,20 @@ "type": "tidelift" } ], - "time": "2022-01-07T00:28:17+00:00" + "time": "2022-07-20T13:00:38+00:00" }, { "name": "symfony/translation-contracts", - "version": "v2.5.0", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "d28150f0f44ce854e942b671fc2620a98aae1b1e" + "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/d28150f0f44ce854e942b671fc2620a98aae1b1e", - "reference": "d28150f0f44ce854e942b671fc2620a98aae1b1e", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/136b19dd05cdf0709db6537d058bcab6dd6e2dbe", + "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe", "shasum": "" }, "require": { @@ -5030,7 +5557,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/translation-contracts/tree/v2.5.2" }, "funding": [ { @@ -5046,20 +5573,20 @@ "type": "tidelift" } ], - "time": "2021-08-17T14:20:01+00:00" + "time": "2022-06-27T16:58:25+00:00" }, { "name": "symfony/var-dumper", - "version": "v5.4.3", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "970a01f208bf895c5f327ba40b72288da43adec4" + "reference": "b8f306d7b8ef34fb3db3305be97ba8e088fb4861" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/970a01f208bf895c5f327ba40b72288da43adec4", - "reference": "970a01f208bf895c5f327ba40b72288da43adec4", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b8f306d7b8ef34fb3db3305be97ba8e088fb4861", + "reference": "b8f306d7b8ef34fb3db3305be97ba8e088fb4861", "shasum": "" }, "require": { @@ -5119,7 +5646,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.4.3" + "source": "https://github.com/symfony/var-dumper/tree/v5.4.11" }, "funding": [ { @@ -5135,72 +5662,147 @@ "type": "tidelift" } ], - "time": "2022-01-17T16:30:37+00:00" + "time": "2022-07-20T13:00:38+00:00" }, { - "name": "tijsverkoyen/css-to-inline-styles", - "version": "2.2.4", + "name": "symfony/yaml", + "version": "v5.4.11", "source": { "type": "git", - "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", - "reference": "da444caae6aca7a19c0c140f68c6182e337d5b1c" + "url": "https://github.com/symfony/yaml.git", + "reference": "05d4ea560f3402c6c116afd99fdc66e60eda227e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/da444caae6aca7a19c0c140f68c6182e337d5b1c", - "reference": "da444caae6aca7a19c0c140f68c6182e337d5b1c", + "url": "https://api.github.com/repos/symfony/yaml/zipball/05d4ea560f3402c6c116afd99fdc66e60eda227e", + "reference": "05d4ea560f3402c6c116afd99fdc66e60eda227e", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-libxml": "*", - "php": "^5.5 || ^7.0 || ^8.0", - "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<5.3" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10" + "symfony/console": "^5.3|^6.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2.x-dev" - } + "suggest": { + "symfony/console": "For validating YAML files using the lint command" }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", "autoload": { "psr-4": { - "TijsVerkoyen\\CssToInlineStyles\\": "src" - } + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Tijs Verkoyen", - "email": "css_to_inline_styles@verkoyen.eu", - "role": "Developer" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", - "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "description": "Loads and dumps YAML files", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", - "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.4" - }, - "time": "2021-12-08T09:12:39+00:00" - }, - { - "name": "vlucas/phpdotenv", - "version": "v5.4.1", - "source": { - "type": "git", - "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f" + "source": "https://github.com/symfony/yaml/tree/v5.4.11" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/264dce589e7ce37a7ba99cb901eed8249fbec92f", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-06-27T16:58:25+00:00" + }, + { + "name": "tijsverkoyen/css-to-inline-styles", + "version": "2.2.4", + "source": { + "type": "git", + "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", + "reference": "da444caae6aca7a19c0c140f68c6182e337d5b1c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/da444caae6aca7a19c0c140f68c6182e337d5b1c", + "reference": "da444caae6aca7a19c0c140f68c6182e337d5b1c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "php": "^5.5 || ^7.0 || ^8.0", + "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "TijsVerkoyen\\CssToInlineStyles\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Tijs Verkoyen", + "email": "css_to_inline_styles@verkoyen.eu", + "role": "Developer" + } + ], + "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", + "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "support": { + "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.4" + }, + "time": "2021-12-08T09:12:39+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.4.1", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/264dce589e7ce37a7ba99cb901eed8249fbec92f", "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f", "shasum": "" }, @@ -5346,21 +5948,21 @@ }, { "name": "webmozart/assert", - "version": "1.10.0", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "symfony/polyfill-ctype": "^1.8" + "ext-ctype": "*", + "php": "^7.2 || ^8.0" }, "conflict": { "phpstan/phpstan": "<0.12.20", @@ -5398,37 +6000,195 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.10.0" + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + }, + { + "name": "zircote/swagger-php", + "version": "3.3.6", + "source": { + "type": "git", + "url": "https://github.com/zircote/swagger-php.git", + "reference": "5016342f966fca29dda84455de066c5c90d37941" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/5016342f966fca29dda84455de066c5c90d37941", + "reference": "5016342f966fca29dda84455de066c5c90d37941", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.7", + "ext-json": "*", + "php": ">=7.2", + "psr/log": "^1.1 || ^2.0 || ^3.0", + "symfony/finder": ">=2.2", + "symfony/yaml": ">=3.3" }, - "time": "2021-03-09T10:59:23+00:00" + "require-dev": { + "composer/package-versions-deprecated": "1.11.99.2", + "friendsofphp/php-cs-fixer": "^2.17 || ^3.0", + "phpunit/phpunit": ">=8.5.14" + }, + "bin": [ + "bin/openapi" + ], + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "OpenApi\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Robert Allen", + "email": "zircote@gmail.com" + }, + { + "name": "Bob Fanger", + "email": "bfanger@gmail.com", + "homepage": "https://bfanger.nl" + }, + { + "name": "Martin Rademacher", + "email": "mano@radebatz.net", + "homepage": "https://radebatz.net" + } + ], + "description": "swagger-php - Generate interactive documentation for your RESTful API using phpdoc annotations", + "homepage": "https://github.com/zircote/swagger-php/", + "keywords": [ + "api", + "json", + "rest", + "service discovery" + ], + "support": { + "issues": "https://github.com/zircote/swagger-php/issues", + "source": "https://github.com/zircote/swagger-php/tree/3.3.6" + }, + "time": "2022-05-21T01:52:14+00:00" } ], "packages-dev": [ + { + "name": "barryvdh/laravel-debugbar", + "version": "v3.7.0", + "source": { + "type": "git", + "url": "https://github.com/barryvdh/laravel-debugbar.git", + "reference": "3372ed65e6d2039d663ed19aa699956f9d346271" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/3372ed65e6d2039d663ed19aa699956f9d346271", + "reference": "3372ed65e6d2039d663ed19aa699956f9d346271", + "shasum": "" + }, + "require": { + "illuminate/routing": "^7|^8|^9", + "illuminate/session": "^7|^8|^9", + "illuminate/support": "^7|^8|^9", + "maximebf/debugbar": "^1.17.2", + "php": ">=7.2.5", + "symfony/finder": "^5|^6" + }, + "require-dev": { + "mockery/mockery": "^1.3.3", + "orchestra/testbench-dusk": "^5|^6|^7", + "phpunit/phpunit": "^8.5|^9.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.6-dev" + }, + "laravel": { + "providers": [ + "Barryvdh\\Debugbar\\ServiceProvider" + ], + "aliases": { + "Debugbar": "Barryvdh\\Debugbar\\Facades\\Debugbar" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Barryvdh\\Debugbar\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Barry vd. Heuvel", + "email": "barryvdh@gmail.com" + } + ], + "description": "PHP Debugbar integration for Laravel", + "keywords": [ + "debug", + "debugbar", + "laravel", + "profiler", + "webprofiler" + ], + "support": { + "issues": "https://github.com/barryvdh/laravel-debugbar/issues", + "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.7.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2022-07-11T09:26:42+00:00" + }, { "name": "doctrine/instantiator", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^8.0", + "doctrine/coding-standard": "^9", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" }, "type": "library", "autoload": { @@ -5455,7 +6215,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + "source": "https://github.com/doctrine/instantiator/tree/1.4.1" }, "funding": [ { @@ -5471,20 +6231,20 @@ "type": "tidelift" } ], - "time": "2020-11-10T18:47:58+00:00" + "time": "2022-03-03T08:28:38+00:00" }, { "name": "facade/flare-client-php", - "version": "1.9.1", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/facade/flare-client-php.git", - "reference": "b2adf1512755637d0cef4f7d1b54301325ac78ed" + "reference": "213fa2c69e120bca4c51ba3e82ed1834ef3f41b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/facade/flare-client-php/zipball/b2adf1512755637d0cef4f7d1b54301325ac78ed", - "reference": "b2adf1512755637d0cef4f7d1b54301325ac78ed", + "url": "https://api.github.com/repos/facade/flare-client-php/zipball/213fa2c69e120bca4c51ba3e82ed1834ef3f41b8", + "reference": "213fa2c69e120bca4c51ba3e82ed1834ef3f41b8", "shasum": "" }, "require": { @@ -5497,7 +6257,7 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.14", - "phpunit/phpunit": "^7.5.16", + "phpunit/phpunit": "^7.5", "spatie/phpunit-snapshot-assertions": "^2.0" }, "type": "library", @@ -5528,7 +6288,7 @@ ], "support": { "issues": "https://github.com/facade/flare-client-php/issues", - "source": "https://github.com/facade/flare-client-php/tree/1.9.1" + "source": "https://github.com/facade/flare-client-php/tree/1.10.0" }, "funding": [ { @@ -5536,20 +6296,20 @@ "type": "github" } ], - "time": "2021-09-13T12:16:46+00:00" + "time": "2022-08-09T11:23:57+00:00" }, { "name": "facade/ignition", - "version": "2.17.4", + "version": "2.17.6", "source": { "type": "git", "url": "https://github.com/facade/ignition.git", - "reference": "95c80bd35ee6858e9e1439b2f6a698295eeb2070" + "reference": "6acd82e986a2ecee89e2e68adfc30a1936d1ab7c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/facade/ignition/zipball/95c80bd35ee6858e9e1439b2f6a698295eeb2070", - "reference": "95c80bd35ee6858e9e1439b2f6a698295eeb2070", + "url": "https://api.github.com/repos/facade/ignition/zipball/6acd82e986a2ecee89e2e68adfc30a1936d1ab7c", + "reference": "6acd82e986a2ecee89e2e68adfc30a1936d1ab7c", "shasum": "" }, "require": { @@ -5614,7 +6374,7 @@ "issues": "https://github.com/facade/ignition/issues", "source": "https://github.com/facade/ignition" }, - "time": "2021-12-27T15:11:24+00:00" + "time": "2022-06-30T18:26:59+00:00" }, { "name": "facade/ignition-contracts", @@ -5671,16 +6431,16 @@ }, { "name": "fakerphp/faker", - "version": "v1.19.0", + "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/FakerPHP/Faker.git", - "reference": "d7f08a622b3346766325488aa32ddc93ccdecc75" + "reference": "37f751c67a5372d4e26353bd9384bc03744ec77b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/d7f08a622b3346766325488aa32ddc93ccdecc75", - "reference": "d7f08a622b3346766325488aa32ddc93ccdecc75", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/37f751c67a5372d4e26353bd9384bc03744ec77b", + "reference": "37f751c67a5372d4e26353bd9384bc03744ec77b", "shasum": "" }, "require": { @@ -5707,7 +6467,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "v1.19-dev" + "dev-main": "v1.20-dev" } }, "autoload": { @@ -5732,9 +6492,9 @@ ], "support": { "issues": "https://github.com/FakerPHP/Faker/issues", - "source": "https://github.com/FakerPHP/Faker/tree/v1.19.0" + "source": "https://github.com/FakerPHP/Faker/tree/v1.20.0" }, - "time": "2022-02-02T17:38:57+00:00" + "time": "2022-07-20T13:12:54+00:00" }, { "name": "filp/whoops", @@ -5860,16 +6620,16 @@ }, { "name": "laravel/sail", - "version": "v1.13.4", + "version": "v1.15.4", "source": { "type": "git", "url": "https://github.com/laravel/sail.git", - "reference": "57d2942d5edd89b2018d0a3447da321fa35baac7" + "reference": "853dea1fa866a52a93beccc4e5affdc49b98e7d5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sail/zipball/57d2942d5edd89b2018d0a3447da321fa35baac7", - "reference": "57d2942d5edd89b2018d0a3447da321fa35baac7", + "url": "https://api.github.com/repos/laravel/sail/zipball/853dea1fa866a52a93beccc4e5affdc49b98e7d5", + "reference": "853dea1fa866a52a93beccc4e5affdc49b98e7d5", "shasum": "" }, "require": { @@ -5916,7 +6676,73 @@ "issues": "https://github.com/laravel/sail/issues", "source": "https://github.com/laravel/sail" }, - "time": "2022-02-17T19:55:30+00:00" + "time": "2022-08-17T13:17:15+00:00" + }, + { + "name": "maximebf/debugbar", + "version": "v1.18.0", + "source": { + "type": "git", + "url": "https://github.com/maximebf/php-debugbar.git", + "reference": "0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6", + "reference": "0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6", + "shasum": "" + }, + "require": { + "php": "^7.1|^8", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^2.6|^3|^4|^5|^6" + }, + "require-dev": { + "phpunit/phpunit": "^7.5.20 || ^9.4.2", + "twig/twig": "^1.38|^2.7|^3.0" + }, + "suggest": { + "kriswallsmith/assetic": "The best way to manage assets", + "monolog/monolog": "Log using Monolog", + "predis/predis": "Redis storage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "DebugBar\\": "src/DebugBar/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Maxime Bouroumeau-Fuseau", + "email": "maxime.bouroumeau@gmail.com", + "homepage": "http://maximebf.com" + }, + { + "name": "Barry vd. Heuvel", + "email": "barryvdh@gmail.com" + } + ], + "description": "Debug bar in the browser for php application", + "homepage": "https://github.com/maximebf/php-debugbar", + "keywords": [ + "debug", + "debugbar" + ], + "support": { + "issues": "https://github.com/maximebf/php-debugbar/issues", + "source": "https://github.com/maximebf/php-debugbar/tree/v1.18.0" + }, + "time": "2021-12-27T18:49:48+00:00" }, { "name": "mockery/mockery", @@ -5992,28 +6818,29 @@ }, { "name": "myclabs/deep-copy", - "version": "1.10.2", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, - "replace": { - "myclabs/deep-copy": "self.version" + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", "autoload": { @@ -6038,7 +6865,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" }, "funding": [ { @@ -6046,7 +6873,7 @@ "type": "tidelift" } ], - "time": "2020-11-13T09:40:50+00:00" + "time": "2022-03-03T13:19:32+00:00" }, { "name": "nunomaduro/collision", @@ -6246,252 +7073,25 @@ }, "time": "2022-02-21T01:04:05+00:00" }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706", - "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0" - }, - "time": "2022-01-04T19:58:01+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.15.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" - }, - "time": "2021-12-08T12:19:24+00:00" - }, { "name": "phpunit/php-code-coverage", - "version": "9.2.11", + "version": "9.2.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "665a1ac0a763c51afc30d6d130dac0813092b17f" + "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/665a1ac0a763c51afc30d6d130dac0813092b17f", - "reference": "665a1ac0a763c51afc30d6d130dac0813092b17f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2593003befdcc10db5e213f9f28814f5aa8ac073", + "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.13.0", + "nikic/php-parser": "^4.14", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -6540,7 +7140,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.11" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.16" }, "funding": [ { @@ -6548,7 +7148,7 @@ "type": "github" } ], - "time": "2022-02-18T12:46:09+00:00" + "time": "2022-08-20T05:26:47+00:00" }, { "name": "phpunit/php-file-iterator", @@ -6793,16 +7393,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.14", + "version": "9.5.23", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "1883687169c017d6ae37c58883ca3994cfc34189" + "reference": "888556852e7e9bbeeedb9656afe46118765ade34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1883687169c017d6ae37c58883ca3994cfc34189", - "reference": "1883687169c017d6ae37c58883ca3994cfc34189", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/888556852e7e9bbeeedb9656afe46118765ade34", + "reference": "888556852e7e9bbeeedb9656afe46118765ade34", "shasum": "" }, "require": { @@ -6817,8 +7417,7 @@ "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", - "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.7", + "phpunit/php-code-coverage": "^9.2.13", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -6832,13 +7431,9 @@ "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^2.3.4", + "sebastian/type": "^3.0", "sebastian/version": "^3.0.2" }, - "require-dev": { - "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0.1" - }, "suggest": { "ext-soap": "*", "ext-xdebug": "*" @@ -6880,7 +7475,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.14" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.23" }, "funding": [ { @@ -6892,7 +7487,7 @@ "type": "github" } ], - "time": "2022-02-18T12:54:07+00:00" + "time": "2022-08-22T14:01:36+00:00" }, { "name": "sebastian/cli-parser", @@ -7260,16 +7855,16 @@ }, { "name": "sebastian/environment", - "version": "5.1.3", + "version": "5.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac" + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", "shasum": "" }, "require": { @@ -7311,7 +7906,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" }, "funding": [ { @@ -7319,7 +7914,7 @@ "type": "github" } ], - "time": "2020-09-28T05:52:38+00:00" + "time": "2022-04-03T09:37:03+00:00" }, { "name": "sebastian/exporter", @@ -7751,28 +8346,28 @@ }, { "name": "sebastian/type", - "version": "2.3.4", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^9.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -7795,7 +8390,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/2.3.4" + "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" }, "funding": [ { @@ -7803,7 +8398,7 @@ "type": "github" } ], - "time": "2021-06-15T12:49:02+00:00" + "time": "2022-03-15T09:54:48+00:00" }, { "name": "sebastian/version", @@ -7918,5 +8513,5 @@ "php": "^7.3|^8.0" }, "platform-dev": [], - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.3.0" } diff --git a/config/acl.php b/config/acl.php new file mode 100644 index 0000000..964dcc7 --- /dev/null +++ b/config/acl.php @@ -0,0 +1,36 @@ + [ + // Users + 'list:users', + 'view:user', + 'create:user', + 'update:user', + 'delete:user', + ], + 'PRODUCT_OWNER' => [ + + // Projects + 'list:projects', + 'view:project', + 'create:project', + 'update:project', + 'delete:project', + + // Tasks + 'list:tasks', + 'view:task', + 'create:task', + 'update:task', + 'assign:task', + 'delete:task', + ], + + 'TEAM_MEMBER' => [ + // Tasks + 'list:own:tasks', + 'view:own:task', + 'update:own:task', + ] +]; diff --git a/config/auth.php b/config/auth.php index d8c6cee..8080450 100644 --- a/config/auth.php +++ b/config/auth.php @@ -40,6 +40,11 @@ 'driver' => 'session', 'provider' => 'users', ], + + 'api' => [ + 'driver' => 'sanctum', + 'provider' => 'users', + ], ], /* diff --git a/config/json-api-paginate.php b/config/json-api-paginate.php new file mode 100644 index 0000000..490ccd7 --- /dev/null +++ b/config/json-api-paginate.php @@ -0,0 +1,58 @@ + 3, + + /* + * The default number of results that will be returned + * when using the JSON API paginator. + */ + 'default_size' => 3, + + /* + * The key of the page[x] query string parameter for page number. + */ + 'number_parameter' => 'pageIndex', + + /* + * The key of the page[x] query string parameter for page size. + */ + 'size_parameter' => 'pageSize', + + /* + * The key of the page[x] query string parameter for cursor. + */ + 'cursor_parameter' => 'cursor', + + /* + * The name of the macro that is added to the Eloquent query builder. + */ + 'method_name' => 'jsonPaginate', + + /* + * If you only need to display Next and Previous links, you may use + * simple pagination to perform a more efficient query. + */ + 'use_simple_pagination' => true, + + /* + * If you want to use cursor pagination, set this to true. + * This would override use_simple_pagination. + */ + 'use_cursor_pagination' => false, + + /* + * Here you can override the base url to be used in the link items. + */ + 'base_url' => null, + + /* + * The name of the query parameter used for pagination + */ + 'pagination_parameter' => 'page', +]; diff --git a/config/l5-swagger.php b/config/l5-swagger.php new file mode 100644 index 0000000..91f32ae --- /dev/null +++ b/config/l5-swagger.php @@ -0,0 +1,294 @@ + 'default', + 'documentations' => [ + 'default' => [ + 'api' => [ + 'title' => 'Open API UI', + ], + + 'routes' => [ + /* + * Route for accessing api documentation interface + */ + 'api' => 'api/documentation', + ], + 'paths' => [ + /* + * Edit to include full URL in ui for assets + */ + 'use_absolute_path' => env('L5_SWAGGER_USE_ABSOLUTE_PATH', true), + + /* + * File name of the generated json documentation file + */ + 'docs_json' => 'api-docs.json', + + /* + * File name of the generated YAML documentation file + */ + 'docs_yaml' => 'api-docs.yaml', + + /* + * Set this to `json` or `yaml` to determine which documentation file to use in UI + */ + 'format_to_use_for_docs' => env('L5_FORMAT_TO_USE_FOR_DOCS', 'json'), + + /* + * Absolute paths to directory containing the swagger annotations are stored. + */ + 'annotations' => [ + base_path('app'), + ], + + ], + ], + ], + 'defaults' => [ + 'routes' => [ + /* + * Route for accessing parsed swagger annotations. + */ + 'docs' => 'docs', + + /* + * Route for Oauth2 authentication callback. + */ + 'oauth2_callback' => 'api/oauth2-callback', + + /* + * Middleware allows to prevent unexpected access to API documentation + */ + 'middleware' => [ + 'api' => [], + 'asset' => [], + 'docs' => [], + 'oauth2_callback' => [], + ], + + /* + * Route Group options + */ + 'group_options' => [], + ], + + 'paths' => [ + /* + * Absolute path to location where parsed annotations will be stored + */ + 'docs' => storage_path('api-docs'), + + /* + * Absolute path to directory where to export views + */ + 'views' => base_path('resources/views/vendor/l5-swagger'), + + /* + * Edit to set the api's base path + */ + 'base' => env('L5_SWAGGER_BASE_PATH', null), + + /* + * Edit to set path where swagger ui assets should be stored + */ + 'swagger_ui_assets_path' => env('L5_SWAGGER_UI_ASSETS_PATH', 'vendor/swagger-api/swagger-ui/dist/'), + + /* + * Absolute path to directories that should be exclude from scanning + * @deprecated Please use `scanOptions.exclude` + * `scanOptions.exclude` overwrites this + */ + 'excludes' => [], + ], + + 'scanOptions' => [ + /** + * analyser: defaults to \OpenApi\StaticAnalyser . + * + * @see \OpenApi\scan + */ + 'analyser' => null, + + /** + * analysis: defaults to a new \OpenApi\Analysis . + * + * @see \OpenApi\scan + */ + 'analysis' => null, + + /** + * Custom query path processors classes. + * + * @link https://github.com/zircote/swagger-php/tree/master/Examples/schema-query-parameter-processor + * @see \OpenApi\scan + */ + 'processors' => [ + // new \App\SwaggerProcessors\SchemaQueryParameter(), + ], + + /** + * pattern: string $pattern File pattern(s) to scan (default: *.php) . + * + * @see \OpenApi\scan + */ + 'pattern' => null, + + /* + * Absolute path to directories that should be exclude from scanning + * @note This option overwrites `paths.excludes` + * @see \OpenApi\scan + */ + 'exclude' => [], + ], + + /* + * API security definitions. Will be generated into documentation file. + */ + 'securityDefinitions' => [ + 'securitySchemes' => [ + /* + * Examples of Security schemes + */ + /* + 'api_key_security_example' => [ // Unique name of security + 'type' => 'apiKey', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2". + 'description' => 'A short description for security scheme', + 'name' => 'api_key', // The name of the header or query parameter to be used. + 'in' => 'header', // The location of the API key. Valid values are "query" or "header". + ], + 'oauth2_security_example' => [ // Unique name of security + 'type' => 'oauth2', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2". + 'description' => 'A short description for oauth2 security scheme.', + 'flow' => 'implicit', // The flow used by the OAuth2 security scheme. Valid values are "implicit", "password", "application" or "accessCode". + 'authorizationUrl' => 'http://example.com/auth', // The authorization URL to be used for (implicit/accessCode) + //'tokenUrl' => 'http://example.com/auth' // The authorization URL to be used for (password/application/accessCode) + 'scopes' => [ + 'read:projects' => 'read your projects', + 'write:projects' => 'modify projects in your account', + ] + ], + */ + + /* Open API 3.0 support + 'passport' => [ // Unique name of security + 'type' => 'oauth2', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2". + 'description' => 'Laravel passport oauth2 security.', + 'in' => 'header', + 'scheme' => 'https', + 'flows' => [ + "password" => [ + "authorizationUrl" => config('app.url') . '/oauth/authorize', + "tokenUrl" => config('app.url') . '/oauth/token', + "refreshUrl" => config('app.url') . '/token/refresh', + "scopes" => [] + ], + ], + ], + */ + 'sanctum' => [ // Unique name of security + 'type' => 'apiKey', // Valid values are "basic", "apiKey" or "oauth2". + 'description' => 'Enter token in format (Bearer )', + 'name' => 'Authorization', // The name of the header or query parameter to be used. + 'in' => 'header', // The location of the API key. Valid values are "query" or "header". + ], + ], + 'security' => [ + /* + * Examples of Securities + */ + [ + /* + 'oauth2_security_example' => [ + 'read', + 'write' + ], + + 'passport' => [] + */ + ], + ], + ], + + /* + * Set this to `true` in development mode so that docs would be regenerated on each request + * Set this to `false` to disable swagger generation on production + */ + 'generate_always' => env('L5_SWAGGER_GENERATE_ALWAYS', true), + + /* + * Set this to `true` to generate a copy of documentation in yaml format + */ + 'generate_yaml_copy' => env('L5_SWAGGER_GENERATE_YAML_COPY', false), + + /* + * Edit to trust the proxy's ip address - needed for AWS Load Balancer + * string[] + */ + 'proxy' => false, + + /* + * Configs plugin allows to fetch external configs instead of passing them to SwaggerUIBundle. + * See more at: https://github.com/swagger-api/swagger-ui#configs-plugin + */ + 'additional_config_url' => null, + + /* + * Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), + * 'method' (sort by HTTP method). + * Default is the order returned by the server unchanged. + */ + 'operations_sort' => env('L5_SWAGGER_OPERATIONS_SORT', null), + + /* + * Pass the validatorUrl parameter to SwaggerUi init on the JS side. + * A null value here disables validation. + */ + 'validator_url' => null, + + /* + * Swagger UI configuration parameters + */ + 'ui' => [ + 'display' => [ + /* + * Controls the default expansion setting for the operations and tags. It can be : + * 'list' (expands only the tags), + * 'full' (expands the tags and operations), + * 'none' (expands nothing). + */ + 'doc_expansion' => env('L5_SWAGGER_UI_DOC_EXPANSION', 'none'), + + /** + * If set, enables filtering. The top bar will show an edit box that + * you can use to filter the tagged operations that are shown. Can be + * Boolean to enable or disable, or a string, in which case filtering + * will be enabled using that string as the filter expression. Filtering + * is case-sensitive matching the filter expression anywhere inside + * the tag. + */ + 'filter' => env('L5_SWAGGER_UI_FILTERS', true), // true | false + ], + + 'authorization' => [ + /* + * If set to true, it persists authorization data, and it would not be lost on browser close/refresh + */ + 'persist_authorization' => env('L5_SWAGGER_UI_PERSIST_AUTHORIZATION', false), + + 'oauth2' => [ + /* + * If set to true, adds PKCE to AuthorizationCodeGrant flow + */ + 'use_pkce_with_authorization_code_grant' => false, + ], + ], + ], + /* + * Constants which can be used in annotations + */ + 'constants' => [ + 'L5_SWAGGER_CONST_HOST' => env('L5_SWAGGER_CONST_HOST', 'http://my-default-host.com'), + ], + ], +]; diff --git a/config/responsecache.php b/config/responsecache.php new file mode 100644 index 0000000..d90896e --- /dev/null +++ b/config/responsecache.php @@ -0,0 +1,71 @@ + env('RESPONSE_CACHE_ENABLED', true), + + /* + * The given class will determinate if a request should be cached. The + * default class will cache all successful GET-requests. + * + * You can provide your own class given that it implements the + * CacheProfile interface. + */ + 'cache_profile' => Spatie\ResponseCache\CacheProfiles\CacheAllSuccessfulGetRequests::class, + + /* + * When using the default CacheRequestFilter this setting controls the + * default number of seconds responses must be cached. + */ + 'cache_lifetime_in_seconds' => env('RESPONSE_CACHE_LIFETIME', 60 * 60 * 24 * 7), + + /* + * This setting determines if a http header named with the cache time + * should be added to a cached response. This can be handy when + * debugging. + */ + 'add_cache_time_header' => env('APP_DEBUG', true), + + /* + * This setting determines the name of the http header that contains + * the time at which the response was cached + */ + 'cache_time_header_name' => env('RESPONSE_CACHE_HEADER_NAME', 'laravel-responsecache'), + + /* + * Here you may define the cache store that should be used to store + * requests. This can be the name of any store that is + * configured in app/config/cache.php + */ + 'cache_store' => env('RESPONSE_CACHE_DRIVER', 'file'), + + /* + * Here you may define replacers that dynamically replace content from the response. + * Each replacer must implement the Replacer interface. + */ + 'replacers' => [ + \Spatie\ResponseCache\Replacers\CsrfTokenReplacer::class, + ], + + /* + * If the cache driver you configured supports tags, you may specify a tag name + * here. All responses will be tagged. When clearing the responsecache only + * items with that tag will be flushed. + * + * You may use a string or an array here. + */ + 'cache_tag' => '', + + /* + * This class is responsible for generating a hash for a request. This hash + * is used to look up an cached response. + */ + 'hasher' => \Spatie\ResponseCache\Hasher\DefaultHasher::class, + + /* + * This class is responsible for serializing responses. + */ + 'serializer' => \Spatie\ResponseCache\Serializers\DefaultSerializer::class, +]; diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 621a24e..e944684 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -14,11 +14,13 @@ class CreateUsersTable extends Migration public function up() { Schema::create('users', function (Blueprint $table) { - $table->id(); + $table->uuid('id')->primary(); $table->string('name'); $table->string('email')->unique(); + $table->string('username')->unique(); $table->timestamp('email_verified_at')->nullable(); - $table->string('password'); + $table->string('password')->default(''); + $table->integer('role_id')->nullable(); $table->rememberToken(); $table->timestamps(); }); diff --git a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php index 4315e16..d24fe13 100644 --- a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php +++ b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php @@ -15,7 +15,7 @@ public function up() { Schema::create('personal_access_tokens', function (Blueprint $table) { $table->id(); - $table->morphs('tokenable'); + $table->uuidMorphs('tokenable'); $table->string('name'); $table->string('token', 64)->unique(); $table->text('abilities')->nullable(); diff --git a/database/migrations/2022_08_25_063204_initial_project_migration.php b/database/migrations/2022_08_25_063204_initial_project_migration.php new file mode 100644 index 0000000..59de770 --- /dev/null +++ b/database/migrations/2022_08_25_063204_initial_project_migration.php @@ -0,0 +1,47 @@ +uuid('id')->primary(); + $table->string('name')->unique(); + }); + Schema::create('tasks', function (Blueprint $table) { + $table->uuid('id')->primary(); + $table->string('title'); + $table->string('description'); + $table->string('status'); + $table->uuid('project_id'); + $table->uuid('user_id'); + }); + Schema::create('roles', function (Blueprint $table) { + $table->id(); + $table->string('slug')->unique(); + $table->string('name')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('projects'); + Schema::dropIfExists('tasks'); + Schema::dropIfExists('roles'); + } +} diff --git a/database/seeders/RoleSeeder.php b/database/seeders/RoleSeeder.php new file mode 100644 index 0000000..800d02c --- /dev/null +++ b/database/seeders/RoleSeeder.php @@ -0,0 +1,23 @@ + $value) { + $role = Role::firstOrCreate(['slug'=>$roleKey]); + $role->name = $value; + $role->save(); + } + + } +} diff --git a/database/seeders/User.php b/database/seeders/User.php new file mode 100644 index 0000000..b95d619 --- /dev/null +++ b/database/seeders/User.php @@ -0,0 +1,34 @@ +['name'=>'Admin','username'=>'admin','email'=>'admin@atyantik.com','role_id'=>Role::isAdmin()->first()->id], + 'team'=>['name'=>'Team Member','username'=>'team_member','email'=>'team-member@atyantik.com','role_id'=>Role::isTeamMember()->first()->id], + 'product_owner'=>['name'=>'Product Owner','username'=>'product_owner','email'=>'product-owner@atyantik.com','role_id'=>Role::isProductOwner()->first()->id], + ]; + foreach ($users as $key => $user) { + if(!BaseUser::where(['email'=>$user['email']])->first()) { + $user = BaseUser::create($user); + $user->password = Hash::make($key.'@123'); + $user->save(); + } + } + } +} diff --git a/docker/nginx.conf b/docker/nginx.conf new file mode 100644 index 0000000..d74dfb2 --- /dev/null +++ b/docker/nginx.conf @@ -0,0 +1,35 @@ +server { + listen 80; + root /var/www/public; + + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + + index index.php index.html; + charset utf-8; + + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + + error_page 404 /index.php; + + location ~ \.php$ { + try_files $uri =404; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass 127.0.0.1:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_buffering off; + } + + location / { + try_files $uri $uri/ /index.php?$query_string; + gzip_static on; + } + + location ~ /\.(?!well-known).* { + deny all; + } +} diff --git a/docker/php.ini b/docker/php.ini new file mode 100644 index 0000000..2727278 --- /dev/null +++ b/docker/php.ini @@ -0,0 +1,6 @@ +log_errors=1 +display_errors=1 +post_max_size=40M +upload_max_filesize=40M +display_startup_errors=1 +error_log=/var/log/php/errors.log diff --git a/docker/run.sh b/docker/run.sh new file mode 100644 index 0000000..86398d1 --- /dev/null +++ b/docker/run.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +cd /var/www + +# php artisan migrate:fresh --seed +php artisan cache:clear +php artisan route:cache + +/usr/bin/supervisord -c /etc/supervisord.conf diff --git a/docker/supervisor.conf b/docker/supervisor.conf new file mode 100644 index 0000000..83c0862 --- /dev/null +++ b/docker/supervisor.conf @@ -0,0 +1,71 @@ +[supervisord] +nodaemon=true +loglevel=info +logfile=/var/log/supervisord.log +pidfile=/var/run/supervisord.pid + +[group:laravel-worker] +priority=999 +programs=redis,nginx,php8-fpm +# programs=redis,nginx,php8-fpm,laravel-schedule,laravel-notification,laravel-queue + +[program:nginx] +priority=10 +autostart=true +autorestart=true +stderr_logfile_maxbytes=0 +stdout_logfile_maxbytes=0 +stdout_events_enabled=true +stderr_events_enabled=true +command=/usr/sbin/nginx -g 'daemon off;' +stderr_logfile=/var/log/nginx/error.log +stdout_logfile=/var/log/nginx/access.log + +[program:redis] +priority=10 +autostart=true +autorestart=true +stderr_logfile_maxbytes=0 +stdout_logfile_maxbytes=0 +stdout_events_enabled=true +stderr_events_enabled=true +command=/usr/bin/redis-server +stderr_logfile=/var/log/redis/error.log +stdout_logfile=/var/log/redis/access.log + +[program:php8-fpm] +priority=5 +autostart=true +autorestart=true +stderr_logfile_maxbytes=0 +stdout_logfile_maxbytes=0 +command=/usr/local/sbin/php-fpm -R +stderr_logfile=/var/log/nginx/php-error.log +stdout_logfile=/var/log/nginx/php-access.log + +# [program:laravel-schedule] +# numprocs=1 +# autostart=true +# autorestart=true +# redirect_stderr=true +# process_name=%(program_name)s_%(process_num)02d +# command=php /var/www/artisan schedule:run +# stdout_logfile=/var/log/nginx/schedule.log + +# [program:laravel-notification] +# numprocs=1 +# autostart=true +# autorestart=true +# redirect_stderr=true +# process_name=%(program_name)s_%(process_num)02d +# command=php /var/www/artisan notification:worker +# stdout_logfile=/var/log/nginx/notification.log + +# [program:laravel-queue] +# numprocs=5 +# autostart=true +# autorestart=true +# redirect_stderr=true +# process_name=%(program_name)s_%(process_num)02d +# stdout_logfile=/var/log/nginx/worker.log +# command=php /var/www/artisan queue:work sqs --sleep=3 --tries=3 diff --git a/docs/ProjectManagement.postman_collection.json b/docs/ProjectManagement.postman_collection.json new file mode 100644 index 0000000..c2c2f0e --- /dev/null +++ b/docs/ProjectManagement.postman_collection.json @@ -0,0 +1,512 @@ +{ + "info": { + "_postman_id": "b1745b6b-5e81-4649-818e-8d372141bacb", + "name": "Accenture", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "3060542" + }, + "item": [ + { + "name": "Users (All)", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "3|4444", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "http://localhost:8000/api/v1/users", + "protocol": "http", + "host": [ + "laravel-coding-test-level-2", + "test" + ], + "path": [ + "api", + "v1", + "users" + ] + } + }, + "response": [] + }, + { + "name": "A User", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "3|DHBHYKhEHV9u3ZXDcnDTFWIbUbLfxFm1R0p1IpsF", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "http://localhost:8000/api/v1/users/631ddd759d04487a868afdd1b7ad0cae", + "protocol": "http", + "host": [ + "laravel-coding-test-level-2", + "test" + ], + "path": [ + "api", + "v1", + "users", + "631ddd759d04487a868afdd1b7ad0cae" + ] + } + }, + "response": [] + }, + { + "name": "Store User", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "3|DHBHYKhEHV9u3ZXDcnDTFWIbUbLfxFm1R0p1IpsF", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "username", + "value": "product_owner2", + "type": "text" + }, + { + "key": "password", + "value": "123456", + "type": "text" + }, + { + "key": "role_id", + "value": "2", + "type": "text" + } + ] + }, + "url": { + "raw": "http://localhost:8000/api/v1/users", + "protocol": "http", + "host": [ + "laravel-coding-test-level-2", + "test" + ], + "path": [ + "api", + "v1", + "users" + ] + } + }, + "response": [] + }, + { + "name": "Update User", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "3|DHBHYKhEHV9u3ZXDcnDTFWIbUbLfxFm1R0p1IpsF", + "type": "string" + } + ] + }, + "method": "PUT", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "username", + "value": "team_member_edit", + "type": "text" + }, + { + "key": "password", + "value": "123456", + "type": "text" + }, + { + "key": "role_id", + "value": "3", + "type": "text" + } + ] + }, + "url": { + "raw": "http://localhost:8000/api/v1/users/631ddd759d04487a868afdd1b7ad0cae", + "protocol": "http", + "host": [ + "laravel-coding-test-level-2", + "test" + ], + "path": [ + "api", + "v1", + "users", + "631ddd759d04487a868afdd1b7ad0cae" + ] + } + }, + "response": [] + }, + { + "name": "Update User", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "3|DHBHYKhEHV9u3ZXDcnDTFWIbUbLfxFm1R0p1IpsF", + "type": "string" + } + ] + }, + "method": "PATCH", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "username", + "value": "team_member", + "type": "text" + }, + { + "key": "password", + "value": "123456", + "type": "text" + }, + { + "key": "role_id", + "value": "3", + "type": "text" + } + ] + }, + "url": { + "raw": "http://localhost:8000/api/v1/users/631ddd759d04487a868afdd1b7ad0cae", + "protocol": "http", + "host": [ + "laravel-coding-test-level-2", + "test" + ], + "path": [ + "api", + "v1", + "users", + "631ddd759d04487a868afdd1b7ad0cae" + ] + } + }, + "response": [] + }, + { + "name": "Delete User", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "3|DHBHYKhEHV9u3ZXDcnDTFWIbUbLfxFm1R0p1IpsF", + "type": "string" + } + ] + }, + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "http://localhost:8000/api/v1/users/631ddd759d04487a868afdd1b7ad0cae", + "protocol": "http", + "host": [ + "laravel-coding-test-level-2", + "test" + ], + "path": [ + "api", + "v1", + "users", + "631ddd759d04487a868afdd1b7ad0cae" + ] + } + }, + "response": [] + }, + { + "name": "Projects (Paginate)", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "2|mQ0ZCny8gXXmiY2ZuvjQm31ESrWkHG6kut58LzVv", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "http://localhost:8000/api/v1/projects?q=Project A&pageIndex=2&pageSize=5&sortBy=id&sortDirection=DESC", + "protocol": "http", + "host": [ + "laravel-coding-test-level-2", + "test" + ], + "path": [ + "api", + "v1", + "projects" + ], + "query": [ + { + "key": "q", + "value": "Project A" + }, + { + "key": "pageIndex", + "value": "2" + }, + { + "key": "pageSize", + "value": "5" + }, + { + "key": "sortBy", + "value": "id" + }, + { + "key": "sortDirection", + "value": "DESC" + } + ] + } + }, + "response": [] + }, + { + "name": "Store Project", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "2|mQ0ZCny8gXXmiY2ZuvjQm31ESrWkHG6kut58LzVv", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "name", + "value": "Project A", + "type": "text" + } + ] + }, + "url": { + "raw": "http://localhost:8000/api/v1/projects", + "protocol": "http", + "host": [ + "laravel-coding-test-level-2", + "test" + ], + "path": [ + "api", + "v1", + "projects" + ] + } + }, + "response": [] + }, + { + "name": "Store Task", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "2|mQ0ZCny8gXXmiY2ZuvjQm31ESrWkHG6kut58LzVv", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "title", + "value": "Task A", + "type": "text" + }, + { + "key": "description", + "value": "Sample Desc", + "type": "text" + }, + { + "key": "project_id", + "value": "553f8b2ecf0b4085ac346363cdcfca29", + "type": "text" + }, + { + "key": "user_id", + "value": "631ddd759d04487a868afdd1b7ad0cae", + "type": "text" + } + ] + }, + "url": { + "raw": "http://localhost:8000/api/v1/tasks", + "protocol": "http", + "host": [ + "laravel-coding-test-level-2", + "test" + ], + "path": [ + "api", + "v1", + "tasks" + ] + } + }, + "response": [] + }, + { + "name": "Update Task Status", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "3|DHBHYKhEHV9u3ZXDcnDTFWIbUbLfxFm1R0p1IpsF", + "type": "string" + } + ] + }, + "method": "PUT", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "status", + "value": "IN_PROGRESS", + "type": "text" + } + ] + }, + "url": { + "raw": "http://localhost:8000/api/v1/taskstatus/cbec712866c74cca8fcd6761a7dc2f8e", + "protocol": "http", + "host": [ + "laravel-coding-test-level-2", + "test" + ], + "path": [ + "api", + "v1", + "taskstatus", + "cbec712866c74cca8fcd6761a7dc2f8e" + ] + } + }, + "response": [] + } + ] +} \ No newline at end of file diff --git a/resources/views/vendor/l5-swagger/.gitkeep b/resources/views/vendor/l5-swagger/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resources/views/vendor/l5-swagger/index.blade.php b/resources/views/vendor/l5-swagger/index.blade.php new file mode 100644 index 0000000..da60ada --- /dev/null +++ b/resources/views/vendor/l5-swagger/index.blade.php @@ -0,0 +1,78 @@ + + + + + {{config('l5-swagger.documentations.'.$documentation.'.api.title')}} + + + + + + + +
+ + + + + + diff --git a/routes/api.php b/routes/api.php index eb6fa48..b81b56f 100644 --- a/routes/api.php +++ b/routes/api.php @@ -14,6 +14,13 @@ | */ -Route::middleware('auth:sanctum')->get('/user', function (Request $request) { - return $request->user(); -}); + +Route::prefix('v1')->group(function () { + Route::group(['middleware' => ['auth:api']], function () { + Route::apiResource('users', App\Http\Controllers\UserController::class)->parameters(['users'=>'user_id']); + Route::apiResource('projects', App\Http\Controllers\ProjectController::class)->parameters(['projects'=>'project_id']); + Route::apiResource('tasks', App\Http\Controllers\TaskController::class)->parameters(['tasks'=>'task_id']); + + }); + Route::name('login')->post('users/login', [App\Http\Controllers\UserController::class, 'login']); +}); \ No newline at end of file diff --git a/storage/api-docs/api-docs.json b/storage/api-docs/api-docs.json new file mode 100644 index 0000000..b57788c --- /dev/null +++ b/storage/api-docs/api-docs.json @@ -0,0 +1,328 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Project API API", + "contact": { + "name": "Hiren Shah", + "email": "hiren@atyantik.com" + }, + "license": { + "name": "Properietary", + "url": "https://atyantik.com" + }, + "version": "1.0.0" + }, + "servers": [ + { + "url": "http://localhost:8000/api/v1/" + } + ], + "paths": { + "/users/login": { + "post": { + "tags": [ + "Login" + ], + "summary": "Login as User", + "description": "Login as User", + "requestBody": { + "$ref": "#/components/requestBodies/Login" + }, + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Success" + } + } + } + }, + "400": { + "description": "Invalid Order" + }, + "401": { + "description": "Invalid Credential", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Invalid Client Code" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/users": { + "get": { + "tags": [ + "Users" + ], + "summary": "Get list of users", + "description": "Returns list of users", + "operationId": "getUserList", + "responses": { + "200": { + "description": "Successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserResource" + } + } + } + }, + "401": { + "description": "Unauthenticated" + }, + "403": { + "description": "Forbidden" + } + }, + "security": [ + { + "sanctum": [] + } + ] + }, + "post": { + "tags": [ + "Users" + ], + "summary": "Store new user", + "description": "Returns user data", + "operationId": "storeUser", + "parameters": [ + { + "name": "name", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "email", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "mobile_number", + "in": "query", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "name": "password", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "password_confirmation", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "201": { + "description": "Successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserResource" + } + } + } + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthenticated" + }, + "403": { + "description": "Forbidden" + } + } + } + } + }, + "components": { + "schemas": { + "Error": { + "properties": { + "errorMessage": { + "type": "string" + } + }, + "type": "object" + }, + "Success": { + "properties": { + "message": { + "type": "string" + } + }, + "type": "object" + }, + "Pagination": { + "properties": { + "pagination": { + "properties": { + "total": { + "description": "Total", + "type": "integer" + }, + "count": { + "description": "Count", + "type": "integer" + }, + "pageSize": { + "description": "Per Page", + "type": "integer" + }, + "pageIndex": { + "description": "Current Page", + "type": "integer" + }, + "totalPages": { + "description": "Total Page", + "type": "integer" + }, + "links": { + "properties": { + "first": { + "description": "First Page", + "type": "string" + }, + "last": { + "description": "Last Page", + "type": "string" + }, + "current": { + "description": "Current Page", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "Login": { + "properties": { + "username": { + "description": "username", + "type": "string", + "default": "admin" + }, + "password": { + "description": "password", + "type": "string", + "default": "admin@123" + } + }, + "type": "object" + }, + "UserResource": { + "title": "UserResource", + "description": "User resource", + "xml": { + "name": "UserResource" + } + } + }, + "parameters": { + "Authorization": { + "name": "Authorization", + "in": "header", + "description": "Sanctum Token", + "required": true, + "schema": { + "type": "string" + } + }, + "sortBy": { + "name": "sortBy", + "in": "query", + "description": "Sort Order", + "schema": { + "type": "string" + } + }, + "sortDirection": { + "name": "sortDirection", + "in": "query", + "description": "Sort Direction", + "schema": { + "type": "string", + "enum": [ + "asc", + "desc" + ] + } + }, + "includes": { + "name": "includes", + "in": "query", + "description": "Includes for getting object dependened data", + "schema": { + "type": "array", + "items": { + "type": "string", + "collectionFormat": "csv" + } + } + } + }, + "requestBodies": { + "Login": { + "description": "Login ", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Login" + } + } + } + } + }, + "securitySchemes": { + "sanctum": { + "type": "apiKey", + "description": "Enter token in format (Bearer )", + "name": "Authorization", + "in": "header" + } + } + }, + "security": [ + [] + ] +} \ No newline at end of file diff --git a/storage/debugbar/.gitignore b/storage/debugbar/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/debugbar/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/Feature/ProjectTest.php b/tests/Feature/ProjectTest.php new file mode 100644 index 0000000..b0df027 --- /dev/null +++ b/tests/Feature/ProjectTest.php @@ -0,0 +1,82 @@ +bootUp(); + // create two user + $this->loginAsRole('ADMIN'); + $user1Data=[ + "name" => "Demo User 1", + "email" => "demo-1@atyantik.com", + "username" => "demo-1", + "password" => "demo-1@123", + "password_confirmation" => "demo-1@123", + "role_id" => 3 + ]; + $user2Data=[ + "name" => "Demo User 2", + "email" => "demo-2@atyantik.com", + "username" => "demo-2", + "password" => "demo-2@123", + "password_confirmation" => "demo-2@123", + "role_id" => 3 + ]; + $createUser1Response = $this->post('/api/v1/users', $user1Data); + $createUser2Response = $this->post('/api/v1/users', $user2Data); + $createUser1Response->assertStatus(201); + $createUser2Response->assertStatus(201); + $user1 = json_decode($createUser1Response->getContent()); + $user2 = json_decode($createUser2Response->getContent()); + + // create project + $this->loginAsRole('PRODUCT_OWNER'); + $project = [ + "name" => "Test Project A", + ]; + $createProjectResponse = $this->post('api/v1/projects', $project); + $createProjectResponse->assertStatus(201); + $createProjectResponse->assertJsonPath("data.name", "Test Project A"); + $projectObj = json_decode($createProjectResponse->getContent()); + + $task1Response = $this->post('api/v1/tasks', [ + "title" => "Task 1", + "description" => "Task 1 For User 1", + "project_id" => $projectObj->data->id, + "user_id" => $user1->data->id, + "status" => 'NOT_STARTED' + ]); + $task1Response->assertStatus(201); + $task1Response->assertJsonPath("data.title", "Task 1"); + $task1Response->assertJsonPath("data.status", 'NOT_STARTED'); + $task1Response->assertJsonPath("data.project_id", $projectObj->data->id); + $task1Response->assertJsonPath("data.user_id", $user1->data->id); + + $task2Response = $this->post('/api/v1/tasks', [ + "title" => "Task 2", + "description" => "Task 2 for user 2", + "project_id" => $projectObj->data->id, + "user_id" => $user2->data->id, + "status" => 'NOT_STARTED' + ]); + $task2Response->assertStatus(201); + $task2Response->assertJsonPath("data.title", "Task 2"); + $task2Response->assertJsonPath("data.status", 'NOT_STARTED'); + $task2Response->assertJsonPath("data.project_id", $projectObj->data->id); + $task2Response->assertJsonPath("data.user_id", $user2->data->id); + + $this->shutdown(); + } +} diff --git a/tests/Feature/TeamMemberTest.php b/tests/Feature/TeamMemberTest.php new file mode 100644 index 0000000..6a66b9b --- /dev/null +++ b/tests/Feature/TeamMemberTest.php @@ -0,0 +1,52 @@ +bootUp(); + // create project + $this->loginAsRole('PRODUCT_OWNER'); + $project = [ + "name" => "Test Project A For Status Change", + ]; + $createProjectResponse = $this->post('api/v1/projects', $project); + $createProjectResponse->assertStatus(201); + $createProjectResponse->assertJsonPath("data.name", "Test Project A For Status Change"); + $projectObj = json_decode($createProjectResponse->getContent()); + $existingTeamMember = \App\Models\User::where('email','team-member@atyantik.com')->first(); + + $taskResponse = $this->post('api/v1/tasks', [ + "title" => "Task 1 For Status Change", + "description" => "Task 1 For User 1", + "project_id" => $projectObj->data->id, + "user_id" => $existingTeamMember->id, + "status" => 'NOT_STARTED' + ]); + $taskResponse->assertStatus(201); + $taskObj = json_decode($taskResponse->getContent()); + + $taskResponse->assertJsonPath("data.title", "Task 1 For Status Change"); + $taskResponse->assertJsonPath("data.status", 'NOT_STARTED'); + $taskResponse->assertJsonPath("data.project_id", $projectObj->data->id); + $taskResponse->assertJsonPath("data.user_id", $existingTeamMember->id); + + $this->loginAsRole('TEAM_MEMBER'); + $taskResponse = $this->patch('api/v1/tasks/'.$taskObj->data->id, [ + "status" => 'IN_PROGRESS' + ]); + $taskResponse->assertStatus(200); + + } +} diff --git a/tests/Feature/UserTest.php b/tests/Feature/UserTest.php new file mode 100644 index 0000000..fdb7f27 --- /dev/null +++ b/tests/Feature/UserTest.php @@ -0,0 +1,50 @@ +get('/'); + + $response->assertStatus(200); + } + + public function test_user_create() + { + $this->bootUp(); + $this->loginAsRole('ADMIN'); + + $userData = [ + "name" => "Hiren Test", + "email" => "hiren-test@atyantik.com", + "username" => "hiren-test", + "password" => "hiren-test@123", + "password_confirmation" => "hiren-test@123", + "role_id" => 1 + ]; + $createUserResponse = $this->post('/api/v1/users', $userData); + $checkUserData = [ + "name" => "Hiren Test", + "email" => "hiren-test@atyantik.com", + "username" => "hiren-test", + "role_id" => 1 + ]; + + foreach ($checkUserData as $userKey => $userValue) { + $createUserResponse->assertJsonPath("data.{$userKey}", $userValue); + } + $this->shutdown(); + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php index 2932d4a..01e853e 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -7,4 +7,47 @@ abstract class TestCase extends BaseTestCase { use CreatesApplication; + + protected function bootUp() { + $this->artisan('db:wipe'); + $this->artisan('migrate'); + $this->artisan('db:seed --class="RoleSeeder"'); + $this->artisan('db:seed --class="User"'); + } + + protected function loginAsRole($role = '') { + $loginApiLink = '/api/v1/users/login'; + + // Only admin can create users + + if ($role === 'ADMIN') { + // Login as Admin, PHP unit test case will take care of the + // token/cookie + $this->post($loginApiLink, [ + "username" => "admin", + "password" => "admin@123", + ]); + } + if ($role === 'PRODUCT_OWNER') { + // Login as Admin, PHP unit test case will take care of the + // token/cookie + $this->post($loginApiLink, [ + "username" => "product_owner", + "password" => "product_owner@123", + ]); + } + + if ($role === 'TEAM_MEMBER') { + // Login as Admin, PHP unit test case will take care of the + // token/cookie + $this->post($loginApiLink, [ + "username" => "team", + "password" => "team@123", + ]); + } + } + + protected function shutdown() { + $this->artisan('db:wipe'); + } }