From 109283d3eb2051521b1a92dc3f262c068183addb Mon Sep 17 00:00:00 2001 From: Tahmina Akter Date: Wed, 21 Sep 2022 20:58:36 +0800 Subject: [PATCH 1/6] Create models --- app/Models/Project.php | 14 + app/Models/Task.php | 17 + app/Models/TaskStatus.php | 11 + app/Models/UserRole.php | 14 + composer.lock | 1322 +++++++---------- ...2_09_21_000000_create_user_roles_table.php | 32 + ... 2022_09_21_000001_create_users_table.php} | 4 + ...022_09_21_082945_create_projects_table.php | 32 + ...9_21_083050_create_task_statuses_table.php | 32 + .../2022_09_21_083057_create_tasks_table.php | 41 + database/seeders/DatabaseSeeder.php | 3 + database/seeders/TaskStatusesTableSeeder.php | 44 + database/seeders/UserRolesTableSeeder.php | 38 + database/seeders/UsersTableSeeder.php | 29 + 14 files changed, 864 insertions(+), 769 deletions(-) create mode 100644 app/Models/Project.php create mode 100644 app/Models/Task.php create mode 100644 app/Models/TaskStatus.php create mode 100644 app/Models/UserRole.php create mode 100644 database/migrations/2022_09_21_000000_create_user_roles_table.php rename database/migrations/{2014_10_12_000000_create_users_table.php => 2022_09_21_000001_create_users_table.php} (80%) create mode 100644 database/migrations/2022_09_21_082945_create_projects_table.php create mode 100644 database/migrations/2022_09_21_083050_create_task_statuses_table.php create mode 100644 database/migrations/2022_09_21_083057_create_tasks_table.php create mode 100644 database/seeders/TaskStatusesTableSeeder.php create mode 100644 database/seeders/UserRolesTableSeeder.php create mode 100644 database/seeders/UsersTableSeeder.php diff --git a/app/Models/Project.php b/app/Models/Project.php new file mode 100644 index 0000000..476662e --- /dev/null +++ b/app/Models/Project.php @@ -0,0 +1,14 @@ +=7.2" @@ -502,7 +558,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,99 +570,28 @@ "type": "github" } ], - "time": "2022-02-19T14:17:28+00:00" - }, - { - "name": "fruitcake/php-cors", - "version": "v1.2.0", - "source": { - "type": "git", - "url": "https://github.com/fruitcake/php-cors.git", - "reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/58571acbaa5f9f462c9c77e911700ac66f446d4e", - "reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e", - "shasum": "" - }, - "require": { - "php": "^7.4|^8.0", - "symfony/http-foundation": "^4.4|^5.4|^6" - }, - "require-dev": { - "phpstan/phpstan": "^1.4", - "phpunit/phpunit": "^9", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.1-dev" - } - }, - "autoload": { - "psr-4": { - "Fruitcake\\Cors\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fruitcake", - "homepage": "https://fruitcake.nl" - }, - { - "name": "Barryvdh", - "email": "barryvdh@gmail.com" - } - ], - "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", - "homepage": "https://github.com/fruitcake/php-cors", - "keywords": [ - "cors", - "laravel", - "symfony" - ], - "support": { - "issues": "https://github.com/fruitcake/php-cors/issues", - "source": "https://github.com/fruitcake/php-cors/tree/v1.2.0" - }, - "funding": [ - { - "url": "https://fruitcake.nl", - "type": "custom" - }, - { - "url": "https://github.com/barryvdh", - "type": "github" - } - ], - "time": "2022-02-20T15:07:15+00:00" + "time": "2022-02-23T14:25:13+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 +620,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 +632,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.5.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79" + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ee0a041b1760e6a53d2a39c8c34115adc2af2c79", - "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", "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" @@ -675,10 +660,10 @@ "psr/http-client-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", + "bamarni/composer-bin-plugin": "^1.8.1", "ext-curl": "*", "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.5 || ^9.3.5", + "phpunit/phpunit": "^8.5.29 || ^9.5.23", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -688,8 +673,12 @@ }, "type": "library", "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, "branch-alias": { - "dev-master": "7.4-dev" + "dev-master": "7.5-dev" } }, "autoload": { @@ -755,7 +744,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.5.0" }, "funding": [ { @@ -771,20 +760,20 @@ "type": "tidelift" } ], - "time": "2021-12-06T18:43:05+00:00" + "time": "2022-08-28T15:39:27+00:00" }, { "name": "guzzlehttp/promises", - "version": "1.5.1", + "version": "1.5.2", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da" + "reference": "b94b2807d85443f9719887892882d0329d1e2598" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/fe752aedc9fd8fcca3fe7ad05d419d32998a06da", - "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da", + "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", + "reference": "b94b2807d85443f9719887892882d0329d1e2598", "shasum": "" }, "require": { @@ -800,12 +789,12 @@ } }, "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, "files": [ "src/functions_include.php" - ] + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -839,7 +828,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.5.1" + "source": "https://github.com/guzzle/promises/tree/1.5.2" }, "funding": [ { @@ -855,20 +844,20 @@ "type": "tidelift" } ], - "time": "2021-10-22T20:56:57+00:00" + "time": "2022-08-28T14:55:35+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.1.0", + "version": "2.4.1", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "089edd38f5b8abba6cb01567c2a8aaa47cec4c72" + "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/089edd38f5b8abba6cb01567c2a8aaa47cec4c72", - "reference": "089edd38f5b8abba6cb01567c2a8aaa47cec4c72", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/69568e4293f4fa993f3b0e51c9723e1e17c41379", + "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379", "shasum": "" }, "require": { @@ -882,17 +871,21 @@ "psr/http-message-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", + "bamarni/composer-bin-plugin": "^1.8.1", "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.8 || ^9.3.10" + "phpunit/phpunit": "^8.5.29 || ^9.5.23" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.4-dev" } }, "autoload": { @@ -954,7 +947,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.1" }, "funding": [ { @@ -970,20 +963,20 @@ "type": "tidelift" } ], - "time": "2021-10-06T17:43:30+00:00" + "time": "2022-08-28T14:45:39+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 +1136,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,29 +1201,30 @@ "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.2", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "9e4b005daa20b0c161f3845040046dc9ddc1d74e" + "reference": "47afb7fae28ed29057fdca37e16a84f90cc62fae" }, "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/47afb7fae28ed29057fdca37e16a84f90cc62fae", + "reference": "47afb7fae28ed29057fdca37e16a84f90cc62fae", "shasum": "" }, "require": { "php": "^7.3|^8.0" }, "require-dev": { - "pestphp/pest": "^1.18", - "phpstan/phpstan": "^0.12.98", - "symfony/var-dumper": "^5.3" + "nesbot/carbon": "^2.61", + "pestphp/pest": "^1.21.3", + "phpstan/phpstan": "^1.8.2", + "symfony/var-dumper": "^5.4.11" }, "type": "library", "extra": { @@ -1266,20 +1261,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-09-08T13:45:54+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 +1327,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 +1351,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 +1378,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.3-dev" + "dev-main": "2.4-dev" } }, "autoload": { @@ -1438,7 +1435,7 @@ "type": "tidelift" } ], - "time": "2022-02-13T15:00:57+00:00" + "time": "2022-07-29T10:59:45+00:00" }, { "name": "league/config", @@ -1618,16 +1615,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 +1655,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 +1667,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 +1693,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 +1723,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 +1757,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 +1769,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.62.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "4a54375c21eea4811dbd1149fe6b246517554e78" + "reference": "01bc4cdefe98ef58d1f9cb31bdbbddddf2a88f7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4a54375c21eea4811dbd1149fe6b246517554e78", - "reference": "4a54375c21eea4811dbd1149fe6b246517554e78", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/01bc4cdefe98ef58d1f9cb31bdbbddddf2a88f7a", + "reference": "01bc4cdefe98ef58d1f9cb31bdbbddddf2a88f7a", "shasum": "" }, "require": { @@ -1797,10 +1797,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 +1859,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-09-02T07:48:13+00:00" }, { "name": "nette/schema", @@ -1931,20 +1937,20 @@ }, { "name": "nette/utils", - "version": "v3.2.7", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "0af4e3de4df9f1543534beab255ccf459e7a2c99" + "reference": "02a54c4c872b99e4ec05c4aec54b5a06eb0f6368" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/0af4e3de4df9f1543534beab255ccf459e7a2c99", - "reference": "0af4e3de4df9f1543534beab255ccf459e7a2c99", + "url": "https://api.github.com/repos/nette/utils/zipball/02a54c4c872b99e4ec05c4aec54b5a06eb0f6368", + "reference": "02a54c4c872b99e4ec05c4aec54b5a06eb0f6368", "shasum": "" }, "require": { - "php": ">=7.2 <8.2" + "php": ">=7.2 <8.3" }, "conflict": { "nette/di": "<3.0.6" @@ -2010,22 +2016,22 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v3.2.7" + "source": "https://github.com/nette/utils/tree/v3.2.8" }, - "time": "2022-01-24T11:29:14+00:00" + "time": "2022-09-12T23:36:20+00:00" }, { "name": "nikic/php-parser", - "version": "v4.13.2", + "version": "v4.15.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077" + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" }, "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/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", "shasum": "" }, "require": { @@ -2066,9 +2072,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.15.1" }, - "time": "2021-11-30T19:35:32+00:00" + "time": "2022-09-04T07:30:47+00:00" }, { "name": "opis/closure", @@ -2098,12 +2104,12 @@ } }, "autoload": { - "psr-4": { - "Opis\\Closure\\": "src/" - }, "files": [ "functions.php" - ] + ], + "psr-4": { + "Opis\\Closure\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2137,29 +2143,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 +2202,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 +2214,7 @@ "type": "tidelift" } ], - "time": "2021-12-04T23:24:31+00:00" + "time": "2022-07-30T15:51:26+00:00" }, { "name": "psr/container", @@ -2567,16 +2577,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 +2597,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 +2647,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 +2839,12 @@ } }, "autoload": { - "psr-4": { - "Ramsey\\Uuid\\": "src/" - }, "files": [ "src/functions.php" - ] + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2939,16 +2950,16 @@ }, { "name": "symfony/console", - "version": "v5.4.3", + "version": "v5.4.12", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "a2a86ec353d825c75856c6fd14fac416a7bdb6b8" + "reference": "c072aa8f724c3af64e2c7a96b796a4863d24dba1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a2a86ec353d825c75856c6fd14fac416a7bdb6b8", - "reference": "a2a86ec353d825c75856c6fd14fac416a7bdb6b8", + "url": "https://api.github.com/repos/symfony/console/zipball/c072aa8f724c3af64e2c7a96b796a4863d24dba1", + "reference": "c072aa8f724c3af64e2c7a96b796a4863d24dba1", "shasum": "" }, "require": { @@ -3018,7 +3029,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.3" + "source": "https://github.com/symfony/console/tree/v5.4.12" }, "funding": [ { @@ -3034,20 +3045,20 @@ "type": "tidelift" } ], - "time": "2022-01-26T16:28:35+00:00" + "time": "2022-08-17T13:18:05+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 +3095,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 +3111,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 +3162,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 +3178,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 +3233,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 +3249,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 +3318,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 +3334,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 +3397,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 +3413,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 +3460,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 +3476,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.12", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "ef409ff341a565a3663157d4324536746d49a0c7" + "reference": "f4bfe9611b113b15d98a43da68ec9b5a00d56791" }, "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/f4bfe9611b113b15d98a43da68ec9b5a00d56791", + "reference": "f4bfe9611b113b15d98a43da68ec9b5a00d56791", "shasum": "" }, "require": { @@ -3490,8 +3501,11 @@ "require-dev": { "predis/predis": "~1.0", "symfony/cache": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", "symfony/expression-language": "^4.4|^5.0|^6.0", - "symfony/mime": "^4.4|^5.0|^6.0" + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", + "symfony/mime": "^4.4|^5.0|^6.0", + "symfony/rate-limiter": "^5.2|^6.0" }, "suggest": { "symfony/mime": "To use the file extension guesser" @@ -3522,7 +3536,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.12" }, "funding": [ { @@ -3538,20 +3552,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-08-19T07:33:17+00:00" }, { "name": "symfony/http-kernel", - "version": "v5.4.4", + "version": "v5.4.12", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "49f40347228c773688a0488feea0175aa7f4d268" + "reference": "37f660fa3bcd78fe4893ce23ebe934618ec099be" }, "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/37f660fa3bcd78fe4893ce23ebe934618ec099be", + "reference": "37f660fa3bcd78fe4893ce23ebe934618ec099be", "shasum": "" }, "require": { @@ -3634,7 +3648,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.12" }, "funding": [ { @@ -3650,20 +3664,20 @@ "type": "tidelift" } ], - "time": "2022-01-29T18:08:07+00:00" + "time": "2022-08-26T14:40:40+00:00" }, { "name": "symfony/mime", - "version": "v5.4.3", + "version": "v5.4.12", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "e1503cfb5c9a225350f549d3bb99296f4abfb80f" + "reference": "03876e9c5a36f5b45e7d9a381edda5421eff8a90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/e1503cfb5c9a225350f549d3bb99296f4abfb80f", - "reference": "e1503cfb5c9a225350f549d3bb99296f4abfb80f", + "url": "https://api.github.com/repos/symfony/mime/zipball/03876e9c5a36f5b45e7d9a381edda5421eff8a90", + "reference": "03876e9c5a36f5b45e7d9a381edda5421eff8a90", "shasum": "" }, "require": { @@ -3717,7 +3731,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.4.3" + "source": "https://github.com/symfony/mime/tree/v5.4.12" }, "funding": [ { @@ -3733,20 +3747,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-08-19T14:24:03+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 +3775,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3769,12 +3783,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3799,7 +3813,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 +3829,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 +3857,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3882,7 +3896,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 +3912,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 +3937,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3963,7 +3977,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 +3993,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 +4020,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4050,7 +4064,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 +4080,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 +4105,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4134,7 +4148,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 +4164,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 +4192,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4217,7 +4231,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 +4247,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 +4269,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4293,7 +4307,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 +4323,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 +4345,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4372,7 +4386,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 +4402,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 +4424,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4455,7 +4469,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 +4485,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 +4507,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4534,7 +4548,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 +4564,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 +4610,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 +4626,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 +4700,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 +4716,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 +4783,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 +4799,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.12", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "92043b7d8383e48104e411bc9434b260dbeb5a10" + "reference": "2fc515e512d721bf31ea76bd02fe23ada4640058" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/92043b7d8383e48104e411bc9434b260dbeb5a10", - "reference": "92043b7d8383e48104e411bc9434b260dbeb5a10", + "url": "https://api.github.com/repos/symfony/string/zipball/2fc515e512d721bf31ea76bd02fe23ada4640058", + "reference": "2fc515e512d721bf31ea76bd02fe23ada4640058", "shasum": "" }, "require": { @@ -4820,12 +4834,12 @@ }, "type": "library", "autoload": { - "psr-4": { - "Symfony\\Component\\String\\": "" - }, "files": [ "Resources/functions.php" ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, "exclude-from-classmap": [ "/Tests/" ] @@ -4855,7 +4869,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.3" + "source": "https://github.com/symfony/string/tree/v5.4.12" }, "funding": [ { @@ -4871,20 +4885,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-08-12T17:03:11+00:00" }, { "name": "symfony/translation", - "version": "v5.4.3", + "version": "v5.4.12", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "a9dd7403232c61e87e27fb306bbcd1627f245d70" + "reference": "42ecc77eb4f229ce2df702a648ec93b8478d76ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/a9dd7403232c61e87e27fb306bbcd1627f245d70", - "reference": "a9dd7403232c61e87e27fb306bbcd1627f245d70", + "url": "https://api.github.com/repos/symfony/translation/zipball/42ecc77eb4f229ce2df702a648ec93b8478d76ae", + "reference": "42ecc77eb4f229ce2df702a648ec93b8478d76ae", "shasum": "" }, "require": { @@ -4952,7 +4966,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.12" }, "funding": [ { @@ -4968,20 +4982,20 @@ "type": "tidelift" } ], - "time": "2022-01-07T00:28:17+00:00" + "time": "2022-08-02T15:52:22+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 +5044,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 +5060,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 +5133,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,20 +5149,20 @@ "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", + "version": "2.2.5", "source": { "type": "git", "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", - "reference": "da444caae6aca7a19c0c140f68c6182e337d5b1c" + "reference": "4348a3a06651827a27d989ad1d13efec6bb49b19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/da444caae6aca7a19c0c140f68c6182e337d5b1c", - "reference": "da444caae6aca7a19c0c140f68c6182e337d5b1c", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/4348a3a06651827a27d989ad1d13efec6bb49b19", + "reference": "4348a3a06651827a27d989ad1d13efec6bb49b19", "shasum": "" }, "require": { @@ -5186,9 +5200,9 @@ "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", "support": { "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", - "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.4" + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.5" }, - "time": "2021-12-08T09:12:39+00:00" + "time": "2022-09-12T13:28:28+00:00" }, { "name": "vlucas/phpdotenv", @@ -5346,21 +5360,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 +5412,38 @@ ], "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": "2021-03-09T10:59:23+00:00" + "time": "2022-06-03T18:03:27+00:00" } ], "packages-dev": [ { "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 +5470,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 +5486,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 +5512,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 +5543,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 +5551,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 +5629,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 +5686,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 +5722,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "v1.19-dev" + "dev-main": "v1.20-dev" } }, "autoload": { @@ -5732,9 +5747,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 +5875,16 @@ }, { "name": "laravel/sail", - "version": "v1.13.4", + "version": "v1.16.0", "source": { "type": "git", "url": "https://github.com/laravel/sail.git", - "reference": "57d2942d5edd89b2018d0a3447da321fa35baac7" + "reference": "73030c18b769f27e6f6aacf7848d024fa9a55560" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sail/zipball/57d2942d5edd89b2018d0a3447da321fa35baac7", - "reference": "57d2942d5edd89b2018d0a3447da321fa35baac7", + "url": "https://api.github.com/repos/laravel/sail/zipball/73030c18b769f27e6f6aacf7848d024fa9a55560", + "reference": "73030c18b769f27e6f6aacf7848d024fa9a55560", "shasum": "" }, "require": { @@ -5916,20 +5931,20 @@ "issues": "https://github.com/laravel/sail/issues", "source": "https://github.com/laravel/sail" }, - "time": "2022-02-17T19:55:30+00:00" + "time": "2022-08-31T16:38:14+00:00" }, { "name": "mockery/mockery", - "version": "1.5.0", + "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/mockery/mockery.git", - "reference": "c10a5f6e06fc2470ab1822fa13fa2a7380f8fbac" + "reference": "e92dcc83d5a51851baf5f5591d32cb2b16e3684e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/c10a5f6e06fc2470ab1822fa13fa2a7380f8fbac", - "reference": "c10a5f6e06fc2470ab1822fa13fa2a7380f8fbac", + "url": "https://api.github.com/repos/mockery/mockery/zipball/e92dcc83d5a51851baf5f5591d32cb2b16e3684e", + "reference": "e92dcc83d5a51851baf5f5591d32cb2b16e3684e", "shasum": "" }, "require": { @@ -5986,34 +6001,35 @@ ], "support": { "issues": "https://github.com/mockery/mockery/issues", - "source": "https://github.com/mockery/mockery/tree/1.5.0" + "source": "https://github.com/mockery/mockery/tree/1.5.1" }, - "time": "2022-01-20T13:18:17+00:00" + "time": "2022-09-07T15:32:08+00:00" }, { "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 +6054,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 +6062,7 @@ "type": "tidelift" } ], - "time": "2020-11-13T09:40:50+00:00" + "time": "2022-03-03T13:19:32+00:00" }, { "name": "nunomaduro/collision", @@ -6246,252 +6262,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.17", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "665a1ac0a763c51afc30d6d130dac0813092b17f" + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" }, "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/aa94dc41e8661fe90c7316849907cba3007b10d8", + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", "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 +6329,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.17" }, "funding": [ { @@ -6548,7 +6337,7 @@ "type": "github" } ], - "time": "2022-02-18T12:46:09+00:00" + "time": "2022-08-30T12:24:04+00:00" }, { "name": "phpunit/php-file-iterator", @@ -6793,16 +6582,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.14", + "version": "9.5.24", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "1883687169c017d6ae37c58883ca3994cfc34189" + "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1883687169c017d6ae37c58883ca3994cfc34189", - "reference": "1883687169c017d6ae37c58883ca3994cfc34189", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", + "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", "shasum": "" }, "require": { @@ -6817,8 +6606,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 +6620,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.1", "sebastian/version": "^3.0.2" }, - "require-dev": { - "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0.1" - }, "suggest": { "ext-soap": "*", "ext-xdebug": "*" @@ -6880,7 +6664,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.24" }, "funding": [ { @@ -6892,7 +6676,7 @@ "type": "github" } ], - "time": "2022-02-18T12:54:07+00:00" + "time": "2022-08-30T07:42:16+00:00" }, { "name": "sebastian/cli-parser", @@ -7063,16 +6847,16 @@ }, { "name": "sebastian/comparator", - "version": "4.0.6", + "version": "4.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", "shasum": "" }, "require": { @@ -7125,7 +6909,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" }, "funding": [ { @@ -7133,7 +6917,7 @@ "type": "github" } ], - "time": "2020-10-26T15:49:45+00:00" + "time": "2022-09-14T12:41:17+00:00" }, { "name": "sebastian/complexity", @@ -7260,16 +7044,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 +7095,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,20 +7103,20 @@ "type": "github" } ], - "time": "2020-09-28T05:52:38+00:00" + "time": "2022-04-03T09:37:03+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", "shasum": "" }, "require": { @@ -7388,7 +7172,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" }, "funding": [ { @@ -7396,7 +7180,7 @@ "type": "github" } ], - "time": "2021-11-11T14:18:36+00:00" + "time": "2022-09-14T06:03:37+00:00" }, { "name": "sebastian/global-state", @@ -7751,28 +7535,28 @@ }, { "name": "sebastian/type", - "version": "2.3.4", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", "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.2-dev" } }, "autoload": { @@ -7795,7 +7579,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.2.0" }, "funding": [ { @@ -7803,7 +7587,7 @@ "type": "github" } ], - "time": "2021-06-15T12:49:02+00:00" + "time": "2022-09-12T14:47:03+00:00" }, { "name": "sebastian/version", diff --git a/database/migrations/2022_09_21_000000_create_user_roles_table.php b/database/migrations/2022_09_21_000000_create_user_roles_table.php new file mode 100644 index 0000000..2570abd --- /dev/null +++ b/database/migrations/2022_09_21_000000_create_user_roles_table.php @@ -0,0 +1,32 @@ +id(); + $table->string('role_name'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('user_roles'); + } +} diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2022_09_21_000001_create_users_table.php similarity index 80% rename from database/migrations/2014_10_12_000000_create_users_table.php rename to database/migrations/2022_09_21_000001_create_users_table.php index 621a24e..dc75253 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2022_09_21_000001_create_users_table.php @@ -19,9 +19,13 @@ public function up() $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); + $table->biginteger('role_id')->unsigned(); $table->rememberToken(); $table->timestamps(); }); + Schema::table('users', function($table) { + $table->foreign('role_id')->references('id')->on('user_roles'); + }); } /** diff --git a/database/migrations/2022_09_21_082945_create_projects_table.php b/database/migrations/2022_09_21_082945_create_projects_table.php new file mode 100644 index 0000000..950d255 --- /dev/null +++ b/database/migrations/2022_09_21_082945_create_projects_table.php @@ -0,0 +1,32 @@ +id(); + $table->string('name')->unique(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('projects'); + } +} diff --git a/database/migrations/2022_09_21_083050_create_task_statuses_table.php b/database/migrations/2022_09_21_083050_create_task_statuses_table.php new file mode 100644 index 0000000..0baed2e --- /dev/null +++ b/database/migrations/2022_09_21_083050_create_task_statuses_table.php @@ -0,0 +1,32 @@ +id(); + $table->string('status',200); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('task_statuses'); + } +} diff --git a/database/migrations/2022_09_21_083057_create_tasks_table.php b/database/migrations/2022_09_21_083057_create_tasks_table.php new file mode 100644 index 0000000..8ddad7f --- /dev/null +++ b/database/migrations/2022_09_21_083057_create_tasks_table.php @@ -0,0 +1,41 @@ +id(); + $table->string('title'); + $table->string('description')->nullable(); + $table->biginteger('status_id')->unsigned(); + $table->biginteger('user_id')->unsigned(); + $table->biginteger('project_id')->unsigned(); + $table->timestamps(); + }); + Schema::table('tasks', function($table) { + $table->foreign('user_id')->references('id')->on('users'); + $table->foreign('project_id')->references('id')->on('projects'); + $table->foreign('status_id')->references('id')->on('task_statuses'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('tasks'); + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 57b73b5..1d52728 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -14,5 +14,8 @@ class DatabaseSeeder extends Seeder public function run() { // \App\Models\User::factory(10)->create(); + $this->call(TaskStatusesTableSeeder::class); + $this->call(UserRolesTableSeeder::class); + $this->call(UsersTableSeeder::class); } } diff --git a/database/seeders/TaskStatusesTableSeeder.php b/database/seeders/TaskStatusesTableSeeder.php new file mode 100644 index 0000000..fa1634f --- /dev/null +++ b/database/seeders/TaskStatusesTableSeeder.php @@ -0,0 +1,44 @@ +delete(); + \DB::table('task_statuses')->insert(array ( + 0 => + array ( + 'status' => 'NOT_STARTED', + 'created_at' => '2022-09-21 09:14:10', + 'updated_at' => '2022-09-21 09:14:10', + ), + 1 => + array ( + 'status' => 'IN_PROGRESS', + 'created_at' => '2022-09-21 09:14:10', + 'updated_at' => '2022-09-21 09:14:10', + ), + 2 => + array ( + 'status' => 'READY_FOR_TEST', + 'created_at' => '2022-09-21 09:14:10', + 'updated_at' => '2022-09-21 09:14:10', + ), + 3 => + array ( + 'status' => 'COMPLETED', + 'created_at' => '2022-09-21 09:14:10', + 'updated_at' => '2022-09-21 09:14:10', + ), + )); + } +} diff --git a/database/seeders/UserRolesTableSeeder.php b/database/seeders/UserRolesTableSeeder.php new file mode 100644 index 0000000..a63d5bd --- /dev/null +++ b/database/seeders/UserRolesTableSeeder.php @@ -0,0 +1,38 @@ +delete(); + \DB::table('user_roles')->insert(array ( + 0 => + array ( + 'role_name' => 'ADMIN', + 'created_at' => '2022-09-21 09:14:10', + 'updated_at' => '2022-09-21 09:14:10', + ), + 1 => + array ( + 'role_name' => 'PRODUCT_OWNER', + 'created_at' => '2022-09-21 09:14:10', + 'updated_at' => '2022-09-21 09:14:10', + ), + 2 => + array ( + 'role_name' => 'TEAM_MEMBER', + 'created_at' => '2022-09-21 09:14:10', + 'updated_at' => '2022-09-21 09:14:10', + ), + )); + } +} diff --git a/database/seeders/UsersTableSeeder.php b/database/seeders/UsersTableSeeder.php new file mode 100644 index 0000000..013d07f --- /dev/null +++ b/database/seeders/UsersTableSeeder.php @@ -0,0 +1,29 @@ +delete(); + $faker = \Faker\Factory::create(); + $password = Hash::make('admin@123'); + User::create([ + 'name' => 'Administrator', + 'email' => 'admin@test.com', + 'password' => $password, + 'role_id' => 1, + ]); + } +} From 12d39868b804ef54c1ec0b320a945f451c8c8679 Mon Sep 17 00:00:00 2001 From: Tahmina Akter Date: Fri, 23 Sep 2022 08:54:31 +0800 Subject: [PATCH 2/6] Create REST APIs --- app/Http/Controllers/Api/AuthController.php | 106 +++++++++ .../Controllers/Api/ProjectController.php | 181 ++++++++++++++++ app/Http/Controllers/Api/TaskController.php | 202 ++++++++++++++++++ .../Controllers/Api/TaskStatusController.php | 180 ++++++++++++++++ app/Http/Controllers/Api/UserController.php | 167 +++++++++++++++ .../Controllers/Api/UserRoleController.php | 180 ++++++++++++++++ app/Models/Task.php | 3 +- app/Models/TaskStatus.php | 3 + app/Models/User.php | 5 + app/Models/UserRole.php | 1 + routes/api.php | 55 ++++- routes/web.php | 5 + 12 files changed, 1084 insertions(+), 4 deletions(-) create mode 100644 app/Http/Controllers/Api/AuthController.php create mode 100644 app/Http/Controllers/Api/ProjectController.php create mode 100644 app/Http/Controllers/Api/TaskController.php create mode 100644 app/Http/Controllers/Api/TaskStatusController.php create mode 100644 app/Http/Controllers/Api/UserController.php create mode 100644 app/Http/Controllers/Api/UserRoleController.php diff --git a/app/Http/Controllers/Api/AuthController.php b/app/Http/Controllers/Api/AuthController.php new file mode 100644 index 0000000..f2ed973 --- /dev/null +++ b/app/Http/Controllers/Api/AuthController.php @@ -0,0 +1,106 @@ +all(), + [ + 'name' => 'required', + 'email' => 'required|email|unique:users,email', + 'password' => 'required', + 'role_id' => 'required' + ]); + + if($validateUser->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateUser->errors() + ], 401); + } + + $user = User::create([ + 'name' => $request->name, + 'email' => $request->email, + 'password' => Hash::make($request->password), + 'role_id' => $request->role_id + ]); + + return response()->json([ + 'status' => true, + 'message' => 'User Created Successfully', + 'token' => $user->createToken("API TOKEN")->plainTextToken + ], 200); + + } catch (\Throwable $th) { + return response()->json([ + 'status' => false, + 'message' => $th->getMessage() + ], 500); + } + } + + /** + * Login The User + * @param Request $request + * @return User + */ + public function loginUser(Request $request) + { + try { + $validateUser = Validator::make($request->all(), + [ + 'email' => 'required|email', + 'password' => 'required' + ]); + + if($validateUser->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateUser->errors() + ], 401); + } + + if(!Auth::attempt($request->only(['email', 'password']))){ + return response()->json([ + 'status' => false, + 'message' => 'Email & Password does not match with our record.', + ], 401); + } + + $user = User::with('userrole')->where('email', $request->email)->first(); + Log::info("enter1=". $user); + + return response()->json([ + 'status' => true, + 'message' => 'User Logged In Successfully', + 'token' => $user->createToken("API TOKEN")->plainTextToken + ], 200); + + } catch (\Throwable $th) { + return response()->json([ + 'status' => false, + 'message' => $th->getMessage() + ], 500); + } + } +} diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php new file mode 100644 index 0000000..4ceddd9 --- /dev/null +++ b/app/Http/Controllers/Api/ProjectController.php @@ -0,0 +1,181 @@ +all(), + [ + 'name' => 'required', + ]); + + if($validateProject->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateProject->errors() + ], 401); + } + + $project = Project::create([ + 'name' => $request->name, + ]); + + return response()->json([ + 'status' => true, + 'message' => 'Project Created Successfully', + ], 200); + + } catch (\Throwable $th) { + return response()->json([ + 'status' => false, + 'message' => $th->getMessage() + ], 500); + } + } + public function get(Request $request) + { + try { + $data = Project::find($request->id); + + if($data){ + http_response_code(200); + return response([ + 'message' => 'Data successfully retrieved.', + 'data' => $data + ]); + } + else{ + http_response_code(200); + return response([ + 'message' => 'No Record Found!!', + ]); + } + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Failed to retrieve data.', + 'errorCode' => 4103 + ],400); + } + } + public function getAll(Request $request) + { + try { + $data = Project::orderby('id', 'desc')->get(); + + http_response_code(200); + return response([ + 'message' => 'Data successfully retrieved.', + 'data' => $data + ]); + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Failed to retrieve data.', + 'errorCode' => 4103 + ],400); + } + } + public function update(Request $request, $id) + { + $validateProject = Validator::make($request->all(), + [ + 'name' => 'required', + ]); + + if($validateProject->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateProject->errors() + ], 401); + } + try { + $data = Project::findOrFail($id); + $data->name = $request->name; + $data->save(); + + http_response_code(200); + return response([ + 'message' => 'Update Successful', + ]); + + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Data failed to be updated.', + 'errorCode' => 4101, + ], 400); + } + } + public function patchupdate(Request $request, $id) + { + $validateProject = Validator::make($request->all(), + [ + 'name' => 'required', + ]); + + if($validateProject->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateProject->errors() + ], 401); + } + try { + $data = Project::findOrFail($id); + $data->name = $request->name; + $data->save(); + + http_response_code(200); + return response([ + 'message' => 'Update Successful', + ]); + + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Data failed to be updated.', + 'errorCode' => 4101, + ], 400); + } + } + public function delete($id) + { + try { + $data = Project::find($id); + $data->delete(); + + http_response_code(200); + return response([ + 'message' => 'Data successfully deleted.', + ]); + + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Data failed to be deleted.', + 'errorCode' => 4102, + ], 400); + } + } +} diff --git a/app/Http/Controllers/Api/TaskController.php b/app/Http/Controllers/Api/TaskController.php new file mode 100644 index 0000000..ef31088 --- /dev/null +++ b/app/Http/Controllers/Api/TaskController.php @@ -0,0 +1,202 @@ +all(), + [ + 'title' => 'required', + 'status_id' => 'required', + 'user_id' => 'required', + 'project_id' => 'required', + ]); + + if($validateTask->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateTask->errors() + ], 401); + } + Log::info("task=". $request->description); + $task = Task::create([ + 'title' => $request->title, + 'description' => $request->description, + 'status_id' => $request->status_id, + 'user_id' => $request->user_id, + 'project_id' => $request->project_id, + ]); + + return response()->json([ + 'status' => true, + 'message' => 'Task Created Successfully', + ], 200); + + } catch (\Throwable $th) { + return response()->json([ + 'status' => false, + 'message' => $th->getMessage() + ], 500); + } + } + public function get(Request $request) + { + try { + $data = Task::find($request->id); + if($data){ + http_response_code(200); + return response([ + 'message' => 'Data successfully retrieved.', + 'data' => $data + ]); + } + else{ + http_response_code(200); + return response([ + 'message' => 'No Record Found!!', + ]); + } + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Failed to retrieve data.', + 'errorCode' => 4103 + ],400); + } + } + public function getAll(Request $request) + { + try { + $data = Task::orderby('id', 'desc')->paginate(2); + + http_response_code(200); + return response([ + 'message' => 'Data successfully retrieved.', + 'data' => $data + ]); + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Failed to retrieve data.', + 'errorCode' => 4103 + ],400); + } + } + public function update(Request $request, $id) + { + $validateTask = Validator::make($request->all(), + [ + 'title' => 'required', + 'status_id' => 'required', + 'user_id' => 'required', + 'project_id' => 'required', + ]); + + if($validateTask->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateTask->errors() + ], 401); + } + try { + $data = Task::findOrFail($id); + $data->title = $request->title; + $data->description = $request->description; + $data->status_id = $request->status_id; + $data->user_id = $request->user_id; + $data->project_id = $request->project_id; + $data->save(); + + http_response_code(200); + return response([ + 'message' => 'Update Successful', + ]); + + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Data failed to be updated.', + 'errorCode' => 4101, + ], 400); + } + } + public function patchupdate(Request $request, $id) + { + $validateTask = Validator::make($request->all(), + [ + 'title' => 'required', + 'status_id' => 'required', + 'user_id' => 'required', + 'project_id' => 'required', + ]); + + if($validateTask->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateTask->errors() + ], 401); + } + try { + $data = Task::findOrFail($id); + $data->title = $request->title; + $data->description = $request->description; + $data->status_id = $request->status_id; + $data->user_id = $request->user_id; + $data->project_id = $request->project_id; + $data->save(); + + http_response_code(200); + return response([ + 'message' => 'Update Successful', + ]); + + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Data failed to be updated.', + 'errorCode' => 4101, + ], 400); + } + } + public function delete($id) + { + try { + $data = Task::find($id); + $data->delete(); + + http_response_code(200); + return response([ + 'message' => 'Data successfully deleted.', + ]); + + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Data failed to be deleted.', + 'errorCode' => 4102, + ], 400); + } + } +} diff --git a/app/Http/Controllers/Api/TaskStatusController.php b/app/Http/Controllers/Api/TaskStatusController.php new file mode 100644 index 0000000..f771ec3 --- /dev/null +++ b/app/Http/Controllers/Api/TaskStatusController.php @@ -0,0 +1,180 @@ +all(), + [ + 'status' => 'required', + ]); + + if($validateStatus->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateStatus->errors() + ], 401); + } + + $status = TaskStatus::create([ + 'status' => $request->status, + ]); + + return response()->json([ + 'status' => true, + 'message' => 'User Role Created Successfully', + ], 200); + + } catch (\Throwable $th) { + return response()->json([ + 'status' => false, + 'message' => $th->getMessage() + ], 500); + } + } + public function get(Request $request) + { + try { + $data = TaskStatus::find($request->id); + + if($data){ + http_response_code(200); + return response([ + 'message' => 'Data successfully retrieved.', + 'data' => $data + ]); + } + else{ + http_response_code(200); + return response([ + 'message' => 'No Record Found!!', + ]); + } + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Failed to retrieve data.', + 'errorCode' => 4103 + ],400); + } + } + public function getAll(Request $request) + { + try { + $data = TaskStatus::orderby('id', 'desc')->get(); + + http_response_code(200); + return response([ + 'message' => 'Data successfully retrieved.', + 'data' => $data + ]); + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Failed to retrieve data.', + 'errorCode' => 4103 + ],400); + } + } + public function update(Request $request, $id) + { + $validateStatus = Validator::make($request->all(), + [ + 'status' => 'required', + ]); + + if($validateStatus->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateStatus->errors() + ], 401); + } + try { + $data = TaskStatus::findOrFail($id); + $data->status = $request->status; + $data->save(); + + http_response_code(200); + return response([ + 'message' => 'Update Successful', + ]); + + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Data failed to be updated.', + 'errorCode' => 4101, + ], 400); + } + } + public function patchupdate(Request $request, $id) + { + $validateStatus = Validator::make($request->all(), + [ + 'status' => 'required', + ]); + + if($validateStatus->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateStatus->errors() + ], 401); + } + try { + $data = TaskStatus::findOrFail($id); + $data->status = $request->status; + $data->save(); + + http_response_code(200); + return response([ + 'message' => 'Update Successful', + ]); + + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Data failed to be updated.', + 'errorCode' => 4101, + ], 400); + } + } + public function delete($id) + { + try { + $data = TaskStatus::find($id); + $data->delete(); + + http_response_code(200); + return response([ + 'message' => 'Data successfully deleted.', + ]); + + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Data failed to be deleted.', + 'errorCode' => 4102, + ], 400); + } + } +} diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php new file mode 100644 index 0000000..007fa1f --- /dev/null +++ b/app/Http/Controllers/Api/UserController.php @@ -0,0 +1,167 @@ +user_id); + + if($data){ + http_response_code(200); + return response([ + 'message' => 'Data successfully retrieved.', + 'data' => $data + ]); + } + else{ + http_response_code(200); + return response([ + 'message' => 'No Record Found!!', + ]); + } + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Failed to retrieve data.', + 'errorCode' => 4103 + ],400); + } + } + public function getAll(Request $request) + { + try { + // Log::info("enter=". auth()->user()->userrole->role_name); + //if (auth()->user()->userrole->role_name == 'ADMIN') { + $data = User::orderby('id', 'desc')->get(); + + http_response_code(200); + return response([ + 'message' => 'Data successfully retrieved.', + 'data' => $data + ]); + // } + // else{ + // http_response_code(200); + // return response([ + // 'message' => 'Only Admin User Can See!!', + // //'data' => $data + // ]); + // } + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Failed to retrieve data.', + 'errorCode' => 4103 + ],400); + } + } + public function update(Request $request, $id) + { + // Log::info("update=". $request->name); + $validateUser = Validator::make($request->all(), + [ + 'name' => 'required', + 'email' => 'required|email', + 'role_id' => 'required' + ]); + + if($validateUser->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateUser->errors() + ], 401); + } + try { + $data = User::findOrFail($id); + $data->name = $request->name; + $data->email = $request->email; + $data->role_id = $request->role_id; + $data->save(); + + http_response_code(200); + return response([ + 'message' => 'Update Successful', + ]); + + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Data failed to be updated.', + 'errorCode' => 4101, + ], 400); + } + } + public function patchupdate(Request $request, $id) + { + // Log::info("update=". $request->name); + $validateUser = Validator::make($request->all(), + [ + 'name' => 'required', + 'email' => 'required|email', + 'role_id' => 'required' + ]); + + if($validateUser->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateUser->errors() + ], 401); + } + try { + $data = User::findOrFail($id); + $data->name = $request->name; + $data->email = $request->email; + $data->role_id = $request->role_id; + $data->save(); + + http_response_code(200); + return response([ + 'message' => 'Update Successful', + ]); + + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Data failed to be updated.', + 'errorCode' => 4101, + ], 400); + } + } + public function delete($id) + { + try { + $data = User::find($id); + $data->delete(); + + http_response_code(200); + return response([ + 'message' => 'Data successfully deleted.', + ]); + + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Data failed to be deleted.', + 'errorCode' => 4102, + ], 400); + } + } +} diff --git a/app/Http/Controllers/Api/UserRoleController.php b/app/Http/Controllers/Api/UserRoleController.php new file mode 100644 index 0000000..ad41434 --- /dev/null +++ b/app/Http/Controllers/Api/UserRoleController.php @@ -0,0 +1,180 @@ +all(), + [ + 'role_name' => 'required', + ]); + + if($validateRole->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateRole->errors() + ], 401); + } + + $role = UserRole::create([ + 'role_name' => $request->role_name, + ]); + + return response()->json([ + 'status' => true, + 'message' => 'User Role Created Successfully', + ], 200); + + } catch (\Throwable $th) { + return response()->json([ + 'status' => false, + 'message' => $th->getMessage() + ], 500); + } + } + public function get(Request $request) + { + try { + $data = UserRole::find($request->id); + + if($data){ + http_response_code(200); + return response([ + 'message' => 'Data successfully retrieved.', + 'data' => $data + ]); + } + else{ + http_response_code(200); + return response([ + 'message' => 'No Record Found!!', + ]); + } + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Failed to retrieve data.', + 'errorCode' => 4103 + ],400); + } + } + public function getAll(Request $request) + { + try { + $data = UserRole::orderby('id', 'desc')->get(); + + http_response_code(200); + return response([ + 'message' => 'Data successfully retrieved.', + 'data' => $data + ]); + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Failed to retrieve data.', + 'errorCode' => 4103 + ],400); + } + } + public function update(Request $request, $id) + { + $validateRole = Validator::make($request->all(), + [ + 'role_name' => 'required', + ]); + + if($validateRole->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateRole->errors() + ], 401); + } + try { + $data = UserRole::findOrFail($id); + $data->role_name = $request->role_name; + $data->save(); + + http_response_code(200); + return response([ + 'message' => 'Update Successful', + ]); + + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Data failed to be updated.', + 'errorCode' => 4101, + ], 400); + } + } + public function patchupdate(Request $request, $id) + { + $validateRole = Validator::make($request->all(), + [ + 'role_name' => 'required', + ]); + + if($validateRole->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateRole->errors() + ], 401); + } + try { + $data = UserRole::findOrFail($id); + $data->role_name = $request->role_name; + $data->save(); + + http_response_code(200); + return response([ + 'message' => 'Update Successful', + ]); + + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Data failed to be updated.', + 'errorCode' => 4101, + ], 400); + } + } + public function delete($id) + { + try { + $data = UserRole::find($id); + $data->delete(); + + http_response_code(200); + return response([ + 'message' => 'Data successfully deleted.', + ]); + + } catch (RequestException $r) { + + http_response_code(400); + return response([ + 'message' => 'Data failed to be deleted.', + 'errorCode' => 4102, + ], 400); + } + } +} diff --git a/app/Models/Task.php b/app/Models/Task.php index 228a157..46fb0ce 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -10,7 +10,8 @@ class Task extends Model use HasFactory; protected $fillable = [ 'title', - 'status', + 'description', + 'status_id', 'project_id', 'user_id', ]; diff --git a/app/Models/TaskStatus.php b/app/Models/TaskStatus.php index 3f811fd..0abbd01 100644 --- a/app/Models/TaskStatus.php +++ b/app/Models/TaskStatus.php @@ -8,4 +8,7 @@ class TaskStatus extends Model { use HasFactory; + protected $fillable = [ + 'status' + ]; } diff --git a/app/Models/User.php b/app/Models/User.php index 8996368..1a1df85 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -21,6 +21,7 @@ class User extends Authenticatable 'name', 'email', 'password', + 'role_id', ]; /** @@ -41,4 +42,8 @@ class User extends Authenticatable protected $casts = [ 'email_verified_at' => 'datetime', ]; + public function userrole() + { + return $this->hasOne('App\Models\UserRole', 'id', 'role_id'); + } } diff --git a/app/Models/UserRole.php b/app/Models/UserRole.php index cf7fcb1..6f4b9ec 100644 --- a/app/Models/UserRole.php +++ b/app/Models/UserRole.php @@ -11,4 +11,5 @@ class UserRole extends Model protected $fillable = [ 'role_name' ]; + } diff --git a/routes/api.php b/routes/api.php index eb6fa48..6a2ffc5 100644 --- a/routes/api.php +++ b/routes/api.php @@ -2,7 +2,12 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; - +use App\Http\Controllers\Api\AuthController; +use App\Http\Controllers\Api\UserController; +use App\Http\Controllers\Api\ProjectController; +use App\Http\Controllers\Api\TaskController; +use App\Http\Controllers\Api\UserRoleController; +use App\Http\Controllers\Api\TaskStatusController; /* |-------------------------------------------------------------------------- | API Routes @@ -13,7 +18,51 @@ | is assigned the "api" middleware group. Enjoy building your API! | */ +Route::post('/auth/register', [AuthController::class, 'createUser']); +Route::post('/auth/login', [AuthController::class, 'loginUser']); + +Route::group(["middleware" => "auth:sanctum"], function($router){ + // User Resources + Route::get('/v1/users', [UserController::class, 'getAll'])->name('Get All User List'); + Route::get('/v1/users/{user_id}', [UserController::class, 'get'])->name('Get Single User'); + Route::put('/v1/users/{id}', [UserController::class, 'update'])->name('Put Update User'); + Route::patch('/v1/users/{id}', [UserController::class, 'patchupdate'])->name('Patch Update User'); + Route::delete('/v1/users/{id}', [UserController::class, 'delete'])->name('Delete User'); + + // Project Resources + Route::post('/v1/projects', [ProjectController::class, 'create'])->name('Create New Project'); + Route::get('/v1/projects', [ProjectController::class, 'getAll'])->name('Get All Project List'); + Route::get('/v1/projects/{id}', [ProjectController::class, 'get'])->name('Get Single Project'); + Route::put('/v1/projects/{id}', [ProjectController::class, 'update'])->name('Put Update Project'); + Route::patch('/v1/projects/{id}', [ProjectController::class, 'patchupdate'])->name('Patch Update Project'); + Route::delete('/v1/projects/{id}', [ProjectController::class, 'delete'])->name('Delete Project'); + + // Task Resources + Route::post('/v1/tasks', [TaskController::class, 'create'])->name('Create New Task'); + Route::get('/v1/tasks', [TaskController::class, 'getAll'])->name('Get All Task List'); + Route::get('/v1/tasks/{id}', [TaskController::class, 'get'])->name('Get Single Task'); + Route::put('/v1/tasks/{id}', [TaskController::class, 'update'])->name('Put Update Task'); + Route::patch('/v1/tasks/{id}', [TaskController::class, 'patchupdate'])->name('Patch Update Task'); + Route::delete('/v1/tasks/{id}', [TaskController::class, 'delete'])->name('Delete Task'); -Route::middleware('auth:sanctum')->get('/user', function (Request $request) { - return $request->user(); + // User Role Resources + Route::post('/v1/roles', [UserRoleController::class, 'create'])->name('Create New User Role'); + Route::get('/v1/roles', [UserRoleController::class, 'getAll'])->name('Get All Role List'); + Route::get('/v1/roles/{id}', [UserRoleController::class, 'get'])->name('Get Single Role'); + Route::put('/v1/roles/{id}', [UserRoleController::class, 'update'])->name('Put Update Role'); + Route::patch('/v1/roles/{id}', [UserRoleController::class, 'patchupdate'])->name('Patch Update Role'); + Route::delete('/v1/roles/{id}', [UserRoleController::class, 'delete'])->name('Delete Role'); + + // Task Status Resources + Route::post('/v1/status', [TaskStatusController::class, 'create'])->name('Create New Status'); + Route::get('/v1/status', [TaskStatusController::class, 'getAll'])->name('Get All Status List'); + Route::get('/v1/status/{id}', [TaskStatusController::class, 'get'])->name('Get Single Status'); + Route::put('/v1/status/{id}', [TaskStatusController::class, 'update'])->name('Put Update Status'); + Route::patch('/v1/status/{id}', [TaskStatusController::class, 'patchupdate'])->name('Patch Update Status'); + Route::delete('/v1/status/{id}', [TaskStatusController::class, 'delete'])->name('Delete Status'); }); + +// Route::middleware('auth:sanctum')->get('/user', function (Request $request) { +// return $request->user(); +// }); + diff --git a/routes/web.php b/routes/web.php index b130397..48ccbd3 100644 --- a/routes/web.php +++ b/routes/web.php @@ -16,3 +16,8 @@ Route::get('/', function () { return view('welcome'); }); + +Route::get('login', function () { + return view('welcome'); +}); + From 637b03cd2e3f8e8ace7d71de67937e467b3f3476 Mon Sep 17 00:00:00 2001 From: Tahmina Akter Date: Fri, 23 Sep 2022 17:10:00 +0800 Subject: [PATCH 3/6] Implement features --- .../Controllers/Api/ProjectController.php | 137 ++++++++----- app/Http/Controllers/Api/TaskController.php | 142 ++++++++++---- .../Controllers/Api/TaskStatusController.php | 184 +++++++++++------- app/Http/Controllers/Api/UserController.php | 93 +++++---- .../Controllers/Api/UserRoleController.php | 39 +++- app/Models/Project.php | 7 +- app/Models/Task.php | 12 ++ ...022_09_21_082945_create_projects_table.php | 4 + resources/views/login.blade.php | 132 +++++++++++++ resources/views/register.blade.php | 132 +++++++++++++ resources/views/tasklist.blade.php | 132 +++++++++++++ routes/web.php | 9 +- 12 files changed, 825 insertions(+), 198 deletions(-) create mode 100644 resources/views/login.blade.php create mode 100644 resources/views/register.blade.php create mode 100644 resources/views/tasklist.blade.php diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php index 4ceddd9..0e41bcd 100644 --- a/app/Http/Controllers/Api/ProjectController.php +++ b/app/Http/Controllers/Api/ProjectController.php @@ -16,6 +16,7 @@ class ProjectController extends Controller public function create(Request $request) { try { + if (strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER') { //Validated $validateProject = Validator::make($request->all(), [ @@ -32,12 +33,19 @@ public function create(Request $request) $project = Project::create([ 'name' => $request->name, + 'user_id' => auth()->user()->id, ]); return response()->json([ 'status' => true, 'message' => 'Project Created Successfully', ], 200); + } + else{ + return response([ + 'message' => 'Only PRODUCT_OWNER Role User Can Create Project.', + ]); + } } catch (\Throwable $th) { return response()->json([ @@ -49,8 +57,15 @@ public function create(Request $request) public function get(Request $request) { try { - $data = Project::find($request->id); - + $data = []; + if(strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { + $data = Project::with('projectUser')->find($request->id); + }else if(strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER') { + $data = Project::with('projectUser')->where('user_id','=', auth()->user()->id)->find($request->id); + }else{ + $data = []; + } + // print_r($data); if($data){ http_response_code(200); return response([ @@ -76,7 +91,18 @@ public function get(Request $request) public function getAll(Request $request) { try { - $data = Project::orderby('id', 'desc')->get(); + $data = []; + if(strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { + $data = Project::with('projectUser')->orderby('id', 'desc')->get(); + } + else if(strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER') { + $data = Project::with('projectUser')->where('user_id','=', auth()->user()->id)->orderby('id', 'desc')->get(); + }else{ + return response([ + 'message' => 'Unauthorized User!!', + ]); + } + http_response_code(200); return response([ @@ -94,66 +120,79 @@ public function getAll(Request $request) } public function update(Request $request, $id) { - $validateProject = Validator::make($request->all(), - [ - 'name' => 'required', - ]); - - if($validateProject->fails()){ - return response()->json([ - 'status' => false, - 'message' => 'validation error', - 'errors' => $validateProject->errors() - ], 401); - } try { $data = Project::findOrFail($id); - $data->name = $request->name; - $data->save(); + if(strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER' && auth()->user()->id == $data->user_id) { + $validateProject = Validator::make($request->all(), + [ + 'name' => 'required', + ]); - http_response_code(200); - return response([ - 'message' => 'Update Successful', - ]); + if($validateProject->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateProject->errors() + ], 401); + } + + $data->name = $request->name; + $data->save(); + + return response([ + 'message' => 'Update Successful', + ]); + }else{ + return response([ + 'message' => 'Only Owner Can Update Project', + ]); + } } catch (RequestException $r) { http_response_code(400); return response([ - 'message' => 'Data failed to be updated.', + 'message' => 'Data failed to be updated Project.', 'errorCode' => 4101, ], 400); } } public function patchupdate(Request $request, $id) { - $validateProject = Validator::make($request->all(), - [ - 'name' => 'required', - ]); - - if($validateProject->fails()){ - return response()->json([ - 'status' => false, - 'message' => 'validation error', - 'errors' => $validateProject->errors() - ], 401); - } try { $data = Project::findOrFail($id); - $data->name = $request->name; - $data->save(); + if(strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER' && auth()->user()->id == $data->user_id) { + $validateProject = Validator::make($request->all(), + [ + 'name' => 'required', + ]); - http_response_code(200); - return response([ - 'message' => 'Update Successful', - ]); + if($validateProject->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateProject->errors() + ], 401); + } + + $data->name = $request->name; + $data->save(); + + http_response_code(200); + return response([ + 'message' => 'Update Successful', + ]); + }else{ + return response([ + 'message' => 'Only Owner Can Update Project', + ]); + } } catch (RequestException $r) { http_response_code(400); return response([ - 'message' => 'Data failed to be updated.', + 'message' => 'Data failed to be updated Project.', 'errorCode' => 4101, ], 400); } @@ -162,12 +201,16 @@ public function delete($id) { try { $data = Project::find($id); - $data->delete(); - - http_response_code(200); - return response([ - 'message' => 'Data successfully deleted.', - ]); + if(strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER' && auth()->user()->id == $data->user_id) { + $data->delete(); + return response([ + 'message' => 'Data successfully deleted.', + ]); + }else{ + return response([ + 'message' => 'Only Owner Can Delete Project', + ]); + } } catch (RequestException $r) { diff --git a/app/Http/Controllers/Api/TaskController.php b/app/Http/Controllers/Api/TaskController.php index ef31088..1d55194 100644 --- a/app/Http/Controllers/Api/TaskController.php +++ b/app/Http/Controllers/Api/TaskController.php @@ -17,11 +17,12 @@ class TaskController extends Controller public function create(Request $request) { try { + if (strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER') { //Validated - $validateTask = Validator::make($request->all(), + $validateTask = Validator::make($request->all(), [ 'title' => 'required', - 'status_id' => 'required', + // 'status_id' => 'required', 'user_id' => 'required', 'project_id' => 'required', ]); @@ -33,11 +34,10 @@ public function create(Request $request) 'errors' => $validateTask->errors() ], 401); } - Log::info("task=". $request->description); $task = Task::create([ 'title' => $request->title, 'description' => $request->description, - 'status_id' => $request->status_id, + 'status_id' => 1, // 1 for NOT_STARTED 'user_id' => $request->user_id, 'project_id' => $request->project_id, ]); @@ -46,6 +46,11 @@ public function create(Request $request) 'status' => true, 'message' => 'Task Created Successfully', ], 200); + }else{ + return response([ + 'message' => 'Only PRODUCT_OWNER Role User Can Create Task.', + ]); + } } catch (\Throwable $th) { return response()->json([ @@ -57,7 +62,33 @@ public function create(Request $request) public function get(Request $request) { try { - $data = Task::find($request->id); + if(strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { + $data = Task::with(['taskUser' => function ($q) { + return $q->select('id', 'name'); + }, 'taskProject' => function ($q) { + return $q->select('id', 'name','user_id'); + }, 'taskStatus' => function ($q) { + return $q->select('id', 'status'); + }])->find($request->id); + }else if(strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER') { + $data = Task::with(['taskUser' => function ($q) { + return $q->select('id', 'name'); + }, 'taskProject' => function ($q) { + return $q->select('id', 'name','user_id'); + }, 'taskStatus' => function ($q) { + return $q->select('id', 'status'); + }])->whereHas('taskProject', function ($q) { + return $q->where('user_id', '=', auth()->user()->id); + })->find($request->id); + }else if(strtoupper(auth()->user()->userrole->role_name) == 'TEAM_MEMBER') { + $data = Task::with(['taskUser' => function ($q) { + return $q->select('id', 'name'); + }, 'taskProject' => function ($q) { + return $q->select('id', 'name','user_id'); + }, 'taskStatus' => function ($q) { + return $q->select('id', 'status'); + }])->where('user_id', '=', auth()->user()->id)->find($request->id); + } if($data){ http_response_code(200); return response([ @@ -83,9 +114,35 @@ public function get(Request $request) public function getAll(Request $request) { try { - $data = Task::orderby('id', 'desc')->paginate(2); - - http_response_code(200); + $data = []; + if(strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { + $data = Task::with(['taskUser' => function ($q) { + return $q->select('id', 'name'); + }, 'taskProject' => function ($q) { + return $q->select('id', 'name','user_id'); + }, 'taskStatus' => function ($q) { + return $q->select('id', 'status'); + }])->orderby('id', 'desc')->get(); + }else if(strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER') { + $data = Task::with(['taskUser' => function ($q) { + return $q->select('id', 'name'); + }, 'taskProject' => function ($q) { + return $q->select('id', 'name','user_id'); + }, 'taskStatus' => function ($q) { + return $q->select('id', 'status'); + }])->whereHas('taskProject', function ($q) { + return $q->where('user_id', '=', auth()->user()->id); + })->orderby('id', 'desc')->get(); + }else if(strtoupper(auth()->user()->userrole->role_name) == 'TEAM_MEMBER') { + $data = Task::with(['taskUser' => function ($q) { + return $q->select('id', 'name'); + }, 'taskProject' => function ($q) { + return $q->select('id', 'name','user_id'); + }, 'taskStatus' => function ($q) { + return $q->select('id', 'status'); + }])->orderby('id', 'desc')->where('user_id', '=', auth()->user()->id)->get(); + } + // return view('tasklist', compact('pro')); return response([ 'message' => 'Data successfully retrieved.', 'data' => $data @@ -101,10 +158,13 @@ public function getAll(Request $request) } public function update(Request $request, $id) { - $validateTask = Validator::make($request->all(), + try { + $data = Task::findOrFail($id); + if(strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER') { + $validateTask = Validator::make($request->all(), [ 'title' => 'required', - 'status_id' => 'required', + // 'status_id' => 'required', 'user_id' => 'required', 'project_id' => 'required', ]); @@ -116,11 +176,10 @@ public function update(Request $request, $id) 'errors' => $validateTask->errors() ], 401); } - try { - $data = Task::findOrFail($id); + $data->title = $request->title; $data->description = $request->description; - $data->status_id = $request->status_id; + // $data->status_id = $request->status_id; $data->user_id = $request->user_id; $data->project_id = $request->project_id; $data->save(); @@ -129,6 +188,12 @@ public function update(Request $request, $id) return response([ 'message' => 'Update Successful', ]); + } + else{ + return response([ + 'message' => 'Only Owner Can Update Task', + ]); + } } catch (RequestException $r) { @@ -141,34 +206,37 @@ public function update(Request $request, $id) } public function patchupdate(Request $request, $id) { - $validateTask = Validator::make($request->all(), - [ - 'title' => 'required', - 'status_id' => 'required', - 'user_id' => 'required', - 'project_id' => 'required', - ]); - - if($validateTask->fails()){ - return response()->json([ - 'status' => false, - 'message' => 'validation error', - 'errors' => $validateTask->errors() - ], 401); - } try { $data = Task::findOrFail($id); - $data->title = $request->title; - $data->description = $request->description; + if(strtoupper(auth()->user()->userrole->role_name) == 'TEAM_MEMBER') { + + if(auth()->user()->id != $data->user_id){ + return response([ + 'message' => 'This is not your Task', + ]); + } + $validateTask = Validator::make($request->all(), + [ + 'status_id' => 'required', + ]); + if($validateTask->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateTask->errors() + ], 401); + } $data->status_id = $request->status_id; - $data->user_id = $request->user_id; - $data->project_id = $request->project_id; $data->save(); - - http_response_code(200); return response([ 'message' => 'Update Successful', + 'data' => $data ]); + }else{ + return response([ + 'message' => 'Only Team Member Can Update Task Status', + ]); + } } catch (RequestException $r) { @@ -182,6 +250,7 @@ public function patchupdate(Request $request, $id) public function delete($id) { try { + if(strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER') { $data = Task::find($id); $data->delete(); @@ -189,6 +258,11 @@ public function delete($id) return response([ 'message' => 'Data successfully deleted.', ]); + }else{ + return response([ + 'message' => 'Only Owner Can Delete Task', + ]); + } } catch (RequestException $r) { diff --git a/app/Http/Controllers/Api/TaskStatusController.php b/app/Http/Controllers/Api/TaskStatusController.php index f771ec3..a448c4b 100644 --- a/app/Http/Controllers/Api/TaskStatusController.php +++ b/app/Http/Controllers/Api/TaskStatusController.php @@ -16,6 +16,7 @@ public function create(Request $request) { try { //Validated + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { $validateStatus = Validator::make($request->all(), [ 'status' => 'required', @@ -37,6 +38,11 @@ public function create(Request $request) 'status' => true, 'message' => 'User Role Created Successfully', ], 200); + }else{ + return response([ + 'message' => 'Only ADMIN User Can Create Task Status.', + ]); + } } catch (\Throwable $th) { return response()->json([ @@ -47,126 +53,154 @@ public function create(Request $request) } public function get(Request $request) { + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { try { $data = TaskStatus::find($request->id); if($data){ - http_response_code(200); return response([ 'message' => 'Data successfully retrieved.', 'data' => $data ]); } else{ - http_response_code(200); return response([ 'message' => 'No Record Found!!', ]); } } catch (RequestException $r) { - http_response_code(400); return response([ - 'message' => 'Failed to retrieve data.', + 'message' => 'Failed to retrieve data.', 'errorCode' => 4103 ],400); } + }else{ + return response([ + 'message' => 'Only ADMIN User Can See Status.', + ]); + } } public function getAll(Request $request) { - try { - $data = TaskStatus::orderby('id', 'desc')->get(); - - http_response_code(200); - return response([ - 'message' => 'Data successfully retrieved.', - 'data' => $data - ]); - } catch (RequestException $r) { + + try { + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { + $data = TaskStatus::orderby('id', 'desc')->get(); + return response([ + 'message' => 'Data successfully retrieved.', + 'data' => $data + ]); + }else{ + return response([ + 'message' => 'Only ADMIN User Can See Status.', + ]); + } + } catch (RequestException $r) { - http_response_code(400); - return response([ - 'message' => 'Failed to retrieve data.', - 'errorCode' => 4103 - ],400); - } + return response([ + 'message' => 'Failed to retrieve data.', + 'errorCode' => 4103 + ],400); + } + } public function update(Request $request, $id) { - $validateStatus = Validator::make($request->all(), - [ - 'status' => 'required', - ]); + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { + $validateStatus = Validator::make($request->all(), + [ + 'status' => 'required', + ]); - if($validateStatus->fails()){ - return response()->json([ - 'status' => false, - 'message' => 'validation error', - 'errors' => $validateStatus->errors() - ], 401); - } - try { - $data = TaskStatus::findOrFail($id); - $data->status = $request->status; - $data->save(); + if($validateStatus->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateStatus->errors() + ], 401); + } + try { + $data = TaskStatus::findOrFail($id); + $data->status = $request->status; + $data->save(); - http_response_code(200); - return response([ - 'message' => 'Update Successful', - ]); + http_response_code(200); + return response([ + 'message' => 'Update Successful', + 'data' => $data, + ]); - } catch (RequestException $r) { + } catch (RequestException $r) { - http_response_code(400); - return response([ - 'message' => 'Data failed to be updated.', - 'errorCode' => 4101, - ], 400); + http_response_code(400); + return response([ + 'message' => 'Data failed to be updated.', + 'errorCode' => 4101, + ], 400); + } + }else{ + return response([ + 'message' => 'Only ADMIN User Can Update Status.', + ]); } } public function patchupdate(Request $request, $id) { - $validateStatus = Validator::make($request->all(), - [ - 'status' => 'required', - ]); + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { + $validateStatus = Validator::make($request->all(), + [ + 'status' => 'required', + ]); - if($validateStatus->fails()){ - return response()->json([ - 'status' => false, - 'message' => 'validation error', - 'errors' => $validateStatus->errors() - ], 401); - } - try { - $data = TaskStatus::findOrFail($id); - $data->status = $request->status; - $data->save(); + if($validateStatus->fails()){ + return response()->json([ + 'status' => false, + 'message' => 'validation error', + 'errors' => $validateStatus->errors() + ], 401); + } + try { + $data = TaskStatus::findOrFail($id); + $data->status = $request->status; + $data->save(); - http_response_code(200); - return response([ - 'message' => 'Update Successful', - ]); + http_response_code(200); + return response([ + 'message' => 'Update Successful', + ]); - } catch (RequestException $r) { + } catch (RequestException $r) { - http_response_code(400); + http_response_code(400); + return response([ + 'message' => 'Data failed to be updated.', + 'errorCode' => 4101, + ], 400); + } + }else{ return response([ - 'message' => 'Data failed to be updated.', - 'errorCode' => 4101, - ], 400); - } + 'message' => 'Only ADMIN User Can Update Status.', + ]); + } } public function delete($id) { + try { - $data = TaskStatus::find($id); - $data->delete(); + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { + $data = TaskStatus::find($id); + $data->delete(); - http_response_code(200); - return response([ - 'message' => 'Data successfully deleted.', - ]); + http_response_code(200); + return response([ + 'message' => 'Data successfully deleted.', + ]); + }else{ + return response([ + 'message' => 'Only ADMIN User Can Delete Role.', + ]); + } } catch (RequestException $r) { diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index 007fa1f..e4c7d84 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -15,17 +15,23 @@ class UserController extends Controller public function get(Request $request) { try { - $data = User::find($request->user_id); + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN' || auth()->user()->id == $request->user_id) { + $data = User::with('userrole')->find($request->user_id); + } + else{ + $data = []; + return response([ + 'message' => 'Only ADMIN User Can See.', + ]); + } if($data){ - http_response_code(200); return response([ 'message' => 'Data successfully retrieved.', 'data' => $data ]); } else{ - http_response_code(200); return response([ 'message' => 'No Record Found!!', ]); @@ -42,23 +48,21 @@ public function get(Request $request) public function getAll(Request $request) { try { - // Log::info("enter=". auth()->user()->userrole->role_name); - //if (auth()->user()->userrole->role_name == 'ADMIN') { - $data = User::orderby('id', 'desc')->get(); + // Log::info("enter=". strtoupper(auth()->user()->userrole->role_name)); + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { + $data = User::with('userrole')->orderby('id', 'desc')->get(); - http_response_code(200); return response([ 'message' => 'Data successfully retrieved.', 'data' => $data ]); - // } - // else{ - // http_response_code(200); - // return response([ - // 'message' => 'Only Admin User Can See!!', - // //'data' => $data - // ]); - // } + } + else{ + return response([ + 'message' => 'Only Admin User Can See!!', + //'data' => $data + ]); + } } catch (RequestException $r) { http_response_code(400); @@ -86,20 +90,25 @@ public function update(Request $request, $id) ], 401); } try { - $data = User::findOrFail($id); - $data->name = $request->name; - $data->email = $request->email; - $data->role_id = $request->role_id; - $data->save(); + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { + $data = User::with('userrole')->findOrFail($id); + $data->name = $request->name; + $data->email = $request->email; + $data->role_id = $request->role_id; + $data->save(); - http_response_code(200); - return response([ - 'message' => 'Update Successful', - ]); + return response([ + 'message' => 'Update Successful', + 'data' => $data, + ]); + }else{ + return response([ + 'message' => 'Only Admin User Can Update!!', + ]); + } } catch (RequestException $r) { - http_response_code(400); return response([ 'message' => 'Data failed to be updated.', 'errorCode' => 4101, @@ -112,8 +121,6 @@ public function patchupdate(Request $request, $id) $validateUser = Validator::make($request->all(), [ 'name' => 'required', - 'email' => 'required|email', - 'role_id' => 'required' ]); if($validateUser->fails()){ @@ -124,16 +131,23 @@ public function patchupdate(Request $request, $id) ], 401); } try { - $data = User::findOrFail($id); - $data->name = $request->name; - $data->email = $request->email; - $data->role_id = $request->role_id; - $data->save(); + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { + $data = User::with('userrole')->findOrFail($id); + $data->name = $request->name; + // $data->email = $request->email; + // $data->role_id = $request->role_id; + $data->save(); - http_response_code(200); - return response([ - 'message' => 'Update Successful', - ]); + http_response_code(200); + return response([ + 'message' => 'Update Successful', + 'data' => $data, + ]); + }else{ + return response([ + 'message' => 'Only Admin User Can Update!!', + ]); + } } catch (RequestException $r) { @@ -147,13 +161,18 @@ public function patchupdate(Request $request, $id) public function delete($id) { try { + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { $data = User::find($id); $data->delete(); - http_response_code(200); return response([ 'message' => 'Data successfully deleted.', ]); + }else{ + return response([ + 'message' => 'Only Admin User Can delete.', + ]); + } } catch (RequestException $r) { diff --git a/app/Http/Controllers/Api/UserRoleController.php b/app/Http/Controllers/Api/UserRoleController.php index ad41434..b6b4f08 100644 --- a/app/Http/Controllers/Api/UserRoleController.php +++ b/app/Http/Controllers/Api/UserRoleController.php @@ -16,6 +16,7 @@ public function create(Request $request) { try { //Validated + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { $validateRole = Validator::make($request->all(), [ 'role_name' => 'required', @@ -37,6 +38,11 @@ public function create(Request $request) 'status' => true, 'message' => 'User Role Created Successfully', ], 200); + }else{ + return response([ + 'message' => 'Only ADMIN User Can Create Role.', + ]); + } } catch (\Throwable $th) { return response()->json([ @@ -48,7 +54,14 @@ public function create(Request $request) public function get(Request $request) { try { + $data = []; + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { $data = UserRole::find($request->id); + }else{ + return response([ + 'message' => 'Only ADMIN User Can See Role.', + ]); + } if($data){ http_response_code(200); @@ -75,16 +88,22 @@ public function get(Request $request) public function getAll(Request $request) { try { + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { $data = UserRole::orderby('id', 'desc')->get(); + http_response_code(200); return response([ 'message' => 'Data successfully retrieved.', 'data' => $data ]); + }else{ + return response([ + 'message' => 'Only ADMIN User Can See Roles.', + ]); + } } catch (RequestException $r) { - http_response_code(400); return response([ 'message' => 'Failed to retrieve data.', 'errorCode' => 4103 @@ -93,6 +112,7 @@ public function getAll(Request $request) } public function update(Request $request, $id) { + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { $validateRole = Validator::make($request->all(), [ 'role_name' => 'required', @@ -123,9 +143,15 @@ public function update(Request $request, $id) 'errorCode' => 4101, ], 400); } + }else{ + return response([ + 'message' => 'Only ADMIN User Can Update Role.', + ]); + } } public function patchupdate(Request $request, $id) { + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { $validateRole = Validator::make($request->all(), [ 'role_name' => 'required', @@ -156,10 +182,16 @@ public function patchupdate(Request $request, $id) 'errorCode' => 4101, ], 400); } + }else{ + return response([ + 'message' => 'Only ADMIN User Can Update Role.', + ]); + } } public function delete($id) { try { + if (strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { $data = UserRole::find($id); $data->delete(); @@ -167,6 +199,11 @@ public function delete($id) return response([ 'message' => 'Data successfully deleted.', ]); + }else{ + return response([ + 'message' => 'Only ADMIN User Can Delete Role.', + ]); + } } catch (RequestException $r) { diff --git a/app/Models/Project.php b/app/Models/Project.php index 476662e..040e49c 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -9,6 +9,11 @@ class Project extends Model { use HasFactory; protected $fillable = [ - 'name' + 'name', + 'user_id' ]; + public function projectUser() + { + return $this->hasOne('App\Models\User', 'id', 'user_id'); + } } diff --git a/app/Models/Task.php b/app/Models/Task.php index 46fb0ce..0d7dc3f 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -15,4 +15,16 @@ class Task extends Model 'project_id', 'user_id', ]; + public function taskUser() + { + return $this->hasOne('App\Models\User', 'id', 'user_id'); + } + public function taskProject() + { + return $this->belongsTo('App\Models\Project', 'project_id'); + } + public function taskStatus() + { + return $this->hasOne('App\Models\TaskStatus', 'id', 'status_id'); + } } diff --git a/database/migrations/2022_09_21_082945_create_projects_table.php b/database/migrations/2022_09_21_082945_create_projects_table.php index 950d255..0ce3a56 100644 --- a/database/migrations/2022_09_21_082945_create_projects_table.php +++ b/database/migrations/2022_09_21_082945_create_projects_table.php @@ -16,8 +16,12 @@ public function up() Schema::create('projects', function (Blueprint $table) { $table->id(); $table->string('name')->unique(); + $table->biginteger('user_id')->unsigned(); $table->timestamps(); }); + Schema::table('tasks', function($table) { + $table->foreign('user_id')->references('id')->on('users'); + }); } /** diff --git a/resources/views/login.blade.php b/resources/views/login.blade.php new file mode 100644 index 0000000..5708f86 --- /dev/null +++ b/resources/views/login.blade.php @@ -0,0 +1,132 @@ + + + + + + + Laravel + + + + + + + + + + +
+ @if (Route::has('login')) + + @endif + +
+
+ + + + + +
+ +
+
+
+ + +
+
+ Laravel has wonderful, thorough documentation covering every aspect of the framework. Whether you are new to the framework or have previous experience with Laravel, we recommend reading all of the documentation from beginning to end. +
+
+
+ +
+
+ + +
+ +
+
+ Laracasts offers thousands of video tutorials on Laravel, PHP, and JavaScript development. Check them out, see for yourself, and massively level up your development skills in the process. +
+
+
+ +
+
+ + +
+ +
+
+ Laravel News is a community driven portal and newsletter aggregating all of the latest and most important news in the Laravel ecosystem, including new package releases and tutorials. +
+
+
+ +
+
+ +
Vibrant Ecosystem
+
+ +
+
+ Laravel's robust library of first-party tools and libraries, such as Forge, Vapor, Nova, and Envoyer help you take your projects to the next level. Pair them with powerful open source libraries like Cashier, Dusk, Echo, Horizon, Sanctum, Telescope, and more. +
+
+
+
+
+ +
+
+
+ + + + + + Shop + + + + + + + + Sponsor + +
+
+ +
+ Laravel v{{ Illuminate\Foundation\Application::VERSION }} (PHP v{{ PHP_VERSION }}) +
+
+
+
+ + diff --git a/resources/views/register.blade.php b/resources/views/register.blade.php new file mode 100644 index 0000000..5708f86 --- /dev/null +++ b/resources/views/register.blade.php @@ -0,0 +1,132 @@ + + + + + + + Laravel + + + + + + + + + + +
+ @if (Route::has('login')) + + @endif + +
+
+ + + + + +
+ +
+
+
+ + +
+
+ Laravel has wonderful, thorough documentation covering every aspect of the framework. Whether you are new to the framework or have previous experience with Laravel, we recommend reading all of the documentation from beginning to end. +
+
+
+ +
+
+ + +
+ +
+
+ Laracasts offers thousands of video tutorials on Laravel, PHP, and JavaScript development. Check them out, see for yourself, and massively level up your development skills in the process. +
+
+
+ +
+
+ + +
+ +
+
+ Laravel News is a community driven portal and newsletter aggregating all of the latest and most important news in the Laravel ecosystem, including new package releases and tutorials. +
+
+
+ +
+
+ +
Vibrant Ecosystem
+
+ +
+
+ Laravel's robust library of first-party tools and libraries, such as Forge, Vapor, Nova, and Envoyer help you take your projects to the next level. Pair them with powerful open source libraries like Cashier, Dusk, Echo, Horizon, Sanctum, Telescope, and more. +
+
+
+
+
+ +
+
+
+ + + + + + Shop + + + + + + + + Sponsor + +
+
+ +
+ Laravel v{{ Illuminate\Foundation\Application::VERSION }} (PHP v{{ PHP_VERSION }}) +
+
+
+
+ + diff --git a/resources/views/tasklist.blade.php b/resources/views/tasklist.blade.php new file mode 100644 index 0000000..5708f86 --- /dev/null +++ b/resources/views/tasklist.blade.php @@ -0,0 +1,132 @@ + + + + + + + Laravel + + + + + + + + + + +
+ @if (Route::has('login')) + + @endif + +
+
+ + + + + +
+ +
+
+
+ + +
+
+ Laravel has wonderful, thorough documentation covering every aspect of the framework. Whether you are new to the framework or have previous experience with Laravel, we recommend reading all of the documentation from beginning to end. +
+
+
+ +
+
+ + +
+ +
+
+ Laracasts offers thousands of video tutorials on Laravel, PHP, and JavaScript development. Check them out, see for yourself, and massively level up your development skills in the process. +
+
+
+ +
+
+ + +
+ +
+
+ Laravel News is a community driven portal and newsletter aggregating all of the latest and most important news in the Laravel ecosystem, including new package releases and tutorials. +
+
+
+ +
+
+ +
Vibrant Ecosystem
+
+ +
+
+ Laravel's robust library of first-party tools and libraries, such as Forge, Vapor, Nova, and Envoyer help you take your projects to the next level. Pair them with powerful open source libraries like Cashier, Dusk, Echo, Horizon, Sanctum, Telescope, and more. +
+
+
+
+
+ +
+
+
+ + + + + + Shop + + + + + + + + Sponsor + +
+
+ +
+ Laravel v{{ Illuminate\Foundation\Application::VERSION }} (PHP v{{ PHP_VERSION }}) +
+
+
+
+ + diff --git a/routes/web.php b/routes/web.php index 48ccbd3..a53a9eb 100644 --- a/routes/web.php +++ b/routes/web.php @@ -17,7 +17,10 @@ return view('welcome'); }); -Route::get('login', function () { - return view('welcome'); -}); +Route::get('login', function() { + return view('login'); +})->name('login'); +Route::get('register', function() { + return view('register'); +})->name('register'); From f6e642674f45ffbda67da71f0f7ebf4263ba385e Mon Sep 17 00:00:00 2001 From: Tahmina Akter Date: Sat, 24 Sep 2022 16:02:03 +0800 Subject: [PATCH 4/6] Implement pagination --- .../Controllers/Api/ProjectController.php | 19 ++++++++++++------- app/Models/Project.php | 3 +++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php index 0e41bcd..8cf6ad7 100644 --- a/app/Http/Controllers/Api/ProjectController.php +++ b/app/Http/Controllers/Api/ProjectController.php @@ -10,6 +10,7 @@ use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Log; +use DB; class ProjectController extends Controller { @@ -18,7 +19,7 @@ public function create(Request $request) try { if (strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER') { //Validated - $validateProject = Validator::make($request->all(), + $validateProject = Validator::make($request->all(), [ 'name' => 'required', ]); @@ -59,8 +60,8 @@ public function get(Request $request) try { $data = []; if(strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { - $data = Project::with('projectUser')->find($request->id); - }else if(strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER') { + $data = Project::with('projectUser')->find($request->id); + } else if(strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER') { $data = Project::with('projectUser')->where('user_id','=', auth()->user()->id)->find($request->id); }else{ $data = []; @@ -93,10 +94,14 @@ public function getAll(Request $request) try { $data = []; if(strtoupper(auth()->user()->userrole->role_name) == 'ADMIN') { - $data = Project::with('projectUser')->orderby('id', 'desc')->get(); - } - else if(strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER') { - $data = Project::with('projectUser')->where('user_id','=', auth()->user()->id)->orderby('id', 'desc')->get(); + + \DB::enableQueryLog(); + ; + $data = Project::with('projectUser')->where('name','LIKE','%'.$request->q.'%')->orderby($request->sortBy,$request->sortDirection)->paginate($request->pageSize); + $data->count(); + } else if(strtoupper(auth()->user()->userrole->role_name) == 'PRODUCT_OWNER') { + $data = Project::with('projectUser')->where('user_id','=', auth()->user()->id)->where('name','LIKE','%'.$request->q.'%')->orderby($request->sortBy,$request->sortDirection)->paginate($request->pageSize); + $data->count(); }else{ return response([ 'message' => 'Unauthorized User!!', diff --git a/app/Models/Project.php b/app/Models/Project.php index 040e49c..5bc3fbf 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -4,14 +4,17 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Mehradsadeghi\FilterQueryString\FilterQueryString; class Project extends Model { use HasFactory; + use FilterQueryString; protected $fillable = [ 'name', 'user_id' ]; + protected $filters = ['name','pageIndex','pageSize']; public function projectUser() { return $this->hasOne('App\Models\User', 'id', 'user_id'); From 2193ca41b5516ff653115efb0b2ce2efb4667a90 Mon Sep 17 00:00:00 2001 From: Tahmina Akter Date: Sat, 24 Sep 2022 21:13:18 +0800 Subject: [PATCH 5/6] Write Test --- .../Controllers/Api/ProjectController.php | 1 + app/Http/Controllers/Api/TaskController.php | 4 +- tests/Feature/ProjectTest.php | 71 ++++++++++++++ tests/Feature/TaskTest.php | 35 +++++++ tests/Feature/UserTest.php | 94 +++++++++++++++++++ 5 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 tests/Feature/ProjectTest.php create mode 100644 tests/Feature/TaskTest.php create mode 100644 tests/Feature/UserTest.php diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php index 8cf6ad7..bce13f4 100644 --- a/app/Http/Controllers/Api/ProjectController.php +++ b/app/Http/Controllers/Api/ProjectController.php @@ -40,6 +40,7 @@ public function create(Request $request) return response()->json([ 'status' => true, 'message' => 'Project Created Successfully', + 'id' => $project->id, ], 200); } else{ diff --git a/app/Http/Controllers/Api/TaskController.php b/app/Http/Controllers/Api/TaskController.php index 1d55194..1eb4b49 100644 --- a/app/Http/Controllers/Api/TaskController.php +++ b/app/Http/Controllers/Api/TaskController.php @@ -165,8 +165,8 @@ public function update(Request $request, $id) [ 'title' => 'required', // 'status_id' => 'required', - 'user_id' => 'required', - 'project_id' => 'required', + // 'user_id' => 'required', + // 'project_id' => 'required', ]); if($validateTask->fails()){ diff --git a/tests/Feature/ProjectTest.php b/tests/Feature/ProjectTest.php new file mode 100644 index 0000000..b25cb33 --- /dev/null +++ b/tests/Feature/ProjectTest.php @@ -0,0 +1,71 @@ +get('/api/v1/projects'); + + $response->assertStatus(302); + } + + public function test_project_create_with_user_role_product_owner() + { + $user = User::where('role_id', '=', 2)->first(); //role = product owner + $project = [ + 'name' => 'Project 1', + 'user_id' => $user->id + ]; + $response = $this->actingAs($user) + ->withSession(['banned' => false]) + ->post('/api/v1/projects', $project); + $statusCode = $response->getStatusCode(); + if ($statusCode == 500){ //because project name unique, cant craete duplicate. + $response->assertStatus(500); + }else{ + $response->assertStatus(200); + } + $lp = Project::latest()->first(); + if ($statusCode == 200){ + $userTeams = User::where('role_id', '=', 3)->take(2)->get(); + foreach($userTeams as $key => $ut){ + $this->create_task($this->actingAs($user), $key, $ut, $user, $lp); + } + } + } + + + public function create_task($actingAs, $key, $ut, $user, $lp){ + $task = [ + 'title' => 'Task ' . $key, + 'description' => 'Task ' . $key, + 'project_id' => $lp->id, + 'status_id' => 1, //1 refers not startecd the task yet + 'user_id' => $ut->id, + ]; + $response = $actingAs + ->withSession(['banned' => false]) + ->post('/api/v1/tasks', $task); + $statusCode = $response->getStatusCode(); + if ($statusCode == 500){ + $response->assertStatus(500); + }else{ + $response->assertStatus(200); + } + } +} + diff --git a/tests/Feature/TaskTest.php b/tests/Feature/TaskTest.php new file mode 100644 index 0000000..b217a3c --- /dev/null +++ b/tests/Feature/TaskTest.php @@ -0,0 +1,35 @@ +first(); + $task = Task::where('status_id', '=', 1)->where('user_id', '=', $user->id)->first(); + if($task){ + $ts = [ + 'status_id' => 2, //2 refers status IN_PROGRESS + ]; + $response = $this->actingAs($user) + ->withSession(['banned' => false]) + ->patch('/api/v1/tasks/'. $task->id, $ts); + $statusCode = $response->getStatusCode(); + if ($statusCode == 500){ + $response->assertStatus(500); + }else{ + $response->assertStatus(200); + } + }else{ + $this->assertTrue(true); + } + } +} diff --git a/tests/Feature/UserTest.php b/tests/Feature/UserTest.php new file mode 100644 index 0000000..f8f0ffc --- /dev/null +++ b/tests/Feature/UserTest.php @@ -0,0 +1,94 @@ +get('/users'); + + $response->assertStatus(404); + } + public function test_user_product_owner_register() + { + $user = [ + 'name' => 'Product Owner', + 'email' => 'owner@test.com', + 'password' => 'passwordtest', + 'role_id' => 2 // PRODUCT_OWNER + ]; + + $response = $this->post('/api/auth/register', $user); + $statusCode = $response->getStatusCode(); + if ($statusCode == 401){ + $response->assertStatus(401); + }else{ + $response->assertStatus(200); + } + } + + public function test_user_team_member_one_register() + { + $user = [ + 'name' => 'Team Member 1', + 'email' => 'member1@test.com', + 'password' => 'passwordtest', + 'role_id' => 3 // TEAM_MEMBER + ]; + + $response = $this->post('/api/auth/register', $user); + $statusCode = $response->getStatusCode(); + if ($statusCode == 401){ + $response->assertStatus(401); + }else{ + $response->assertStatus(200); + } + } + + public function test_user_team_member_two_register() + { + $user = [ + 'name' => 'Team Member 2', + 'email' => 'member2@test.com', + 'password' => 'passwordtest', + 'role_id' => 3 // TEAM_MEMBER + ]; + + $response = $this->post('/api/auth/register', $user); + $statusCode = $response->getStatusCode(); + if ($statusCode == 401){ + $response->assertStatus(401); + }else{ + $response->assertStatus(200); + } + } + + public function test_user_team_member_three_register() + { + $user = [ + 'name' => 'Team Member 3', + 'email' => 'member3@test.com', + 'password' => 'passwordtest', + 'role_id' => 3 // TEAM_MEMBER + ]; + + $response = $this->post('/api/auth/register', $user); + $statusCode = $response->getStatusCode(); + if ($statusCode == 401){ + $response->assertStatus(401); + }else{ + $response->assertStatus(200); + } + } +} From 3b689ac7386cbb3ad7b605899e12af5dd5b56e9e Mon Sep 17 00:00:00 2001 From: Tahmina Akter Date: Sat, 24 Sep 2022 21:20:08 +0800 Subject: [PATCH 6/6] Add postman collection & Document to run --- docs/ACN-coding-test.postman_collection.json | 870 +++++++++++++++++++ docs/test-manual.doc | Bin 0 -> 96256 bytes 2 files changed, 870 insertions(+) create mode 100644 docs/ACN-coding-test.postman_collection.json create mode 100644 docs/test-manual.doc diff --git a/docs/ACN-coding-test.postman_collection.json b/docs/ACN-coding-test.postman_collection.json new file mode 100644 index 0000000..453bb33 --- /dev/null +++ b/docs/ACN-coding-test.postman_collection.json @@ -0,0 +1,870 @@ +{ + "info": { + "_postman_id": "e88a99c7-d3d4-45e5-b61a-a89de519c734", + "name": "ACN-coding-test", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "User Registration", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"Test User\",\n \"email\": \"test22@gmail.com\",\n \"password\": \"test@123\",\n \"role_id\":2\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://127.0.0.1:8000/api/auth/register", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "auth", + "register" + ] + }, + "description": "Registration API" + }, + "response": [] + }, + { + "name": "Login Api", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "", + "value": "", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"email\": \"test22@gmail.com\" ,\n \"password\": \"test@123\" \n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://127.0.0.1:8000/api/auth/login", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "auth", + "login" + ] + }, + "description": "Login Api" + }, + "response": [] + }, + { + "name": "Retrieve All Users", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{ADMIN_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "GET", + "header": [], + "url": { + "raw": "http://127.0.0.1:8000/api/v1/users", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "users" + ] + }, + "description": "Only ADMIN USER CAN SEE" + }, + "response": [] + }, + { + "name": "Retrieve Single User", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{ADMIN_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "GET", + "header": [], + "url": { + "raw": "http://127.0.0.1:8000/api/v1/users/4", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "users", + "4" + ] + }, + "description": "Only Admin User Can See all record and others logged in user can see only their record." + }, + "response": [] + }, + { + "name": "Update User Using Put Method", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{ADMIN_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"TEST\",\n \"email\": \"test22@gmail.com\",\n \"role_id\":2\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://127.0.0.1:8000/api/v1/users/4", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "users", + "4" + ] + }, + "description": "Only Admin User Can Update." + }, + "response": [] + }, + { + "name": "Update User Using Patch Method", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{ADMIN_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"test user\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://127.0.0.1:8000/api/v1/users/4", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "users", + "4" + ] + }, + "description": "Only Name Can Update" + }, + "response": [] + }, + { + "name": "Create New User Role", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{ADMIN_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"role_name\":\"STAFF\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://127.0.0.1:8000/api/v1/roles", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "roles" + ] + }, + "description": "Only ADMIN USER can Create Role" + }, + "response": [] + }, + { + "name": "Retrieve All User Roles", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{ADMIN_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "GET", + "header": [], + "url": { + "raw": "http://127.0.0.1:8000/api/v1/roles", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "roles" + ] + }, + "description": "Only ADMIN USER Can See." + }, + "response": [] + }, + { + "name": "Create New Project", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{USER_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"Test Project\",\n \"user_id\": 2\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://127.0.0.1:8000/api/v1/projects", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "projects" + ] + }, + "description": "Only PRODUCT_OWNER Role User Can Create New Project." + }, + "response": [] + }, + { + "name": "Implement Pagination On Project", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{USER_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "GET", + "header": [], + "url": { + "raw": "http://127.0.0.1:8000/api/v1/projects?q=Demo Project&pageIndex=0&pageSize=3&sortBy=name&sortDirection=ASC&page=1", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "projects" + ], + "query": [ + { + "key": "q", + "value": "Demo Project" + }, + { + "key": "pageIndex", + "value": "0" + }, + { + "key": "pageSize", + "value": "3" + }, + { + "key": "sortBy", + "value": "name" + }, + { + "key": "sortDirection", + "value": "ASC" + }, + { + "key": "page", + "value": "1" + } + ] + } + }, + "response": [] + }, + { + "name": "Retrieve Single Project", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{USER_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "GET", + "header": [], + "url": { + "raw": "http://127.0.0.1:8000/api/v1/projects/2", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "projects", + "2" + ] + } + }, + "response": [] + }, + { + "name": "Create New Task", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{USER_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"Demo Task\",\n \"description\": \"Lorem Ipsum\",\n \"status_id\": 1,\n \"user_id\": 5,\n \"project_id\": 6\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://127.0.0.1:8000/api/v1/tasks", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "tasks" + ] + }, + "description": "Only PRODUCT_OWNER can Create a task." + }, + "response": [] + }, + { + "name": "Retrieve All Task List", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{USER_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "GET", + "header": [], + "body": { + "mode": "formdata", + "formdata": [] + }, + "url": { + "raw": "http://127.0.0.1:8000/api/v1/tasks", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "tasks" + ] + } + }, + "response": [] + }, + { + "name": "Retrieve Single Task", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "22|M4UgYWRqc0roPs2bDnWPYwoXMshPUEyDf8XN8qge", + "type": "string" + } + ] + }, + "method": "GET", + "header": [], + "url": { + "raw": "http://127.0.0.1:8000/api/v1/tasks/3", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "tasks", + "3" + ] + } + }, + "response": [] + }, + { + "name": "Update Task Status Only(Team Member)", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "22|M4UgYWRqc0roPs2bDnWPYwoXMshPUEyDf8XN8qge", + "type": "string" + } + ] + }, + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"status_id\": 2\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://127.0.0.1:8000/api/v1/tasks/2", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "tasks", + "2" + ] + }, + "description": "Only Task assign member can update status." + }, + "response": [] + }, + { + "name": "Update Task(Product Owner)", + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"Demo\",\n \"description\": \"Lorem Ipsum\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://127.0.0.1:8000/api/v1/tasks/2", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "tasks", + "2" + ] + }, + "description": "Only PRODUCT_OWNER can update task except status" + }, + "response": [] + }, + { + "name": "Create New Task Status", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{ADMIN_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"status\": \"NOT_DONE\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://127.0.0.1:8000/api/v1/status", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "status" + ] + }, + "description": "Only ADMIN user can create task status" + }, + "response": [] + }, + { + "name": "Retrieve All Task Status", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{ADMIN_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "GET", + "header": [], + "url": { + "raw": "http://127.0.0.1:8000/api/v1/status", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "status" + ] + }, + "description": "Only ADMIN User can See Task Status" + }, + "response": [] + }, + { + "name": "Task Status Update(Only Admin User)", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{ADMIN_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"status\": \"NOT_DONE\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://127.0.0.1:8000/api/v1/status/1", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "status", + "1" + ] + } + }, + "response": [] + }, + { + "name": "Task Status Delete (Only ADMIN User)", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{ADMIN_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "DELETE", + "header": [], + "url": { + "raw": "http://127.0.0.1:8000/api/v1/status/6", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "status", + "6" + ] + } + }, + "response": [] + }, + { + "name": "Update Project", + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{USER_SESSION_JWT}}", + "type": "string" + } + ] + }, + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"DEMO\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://127.0.0.1:8000/api/v1/projects/1", + "protocol": "http", + "host": [ + "127", + "0", + "0", + "1" + ], + "port": "8000", + "path": [ + "api", + "v1", + "projects", + "1" + ] + }, + "description": "Update Project" + }, + "response": [] + } + ] +} \ No newline at end of file diff --git a/docs/test-manual.doc b/docs/test-manual.doc new file mode 100644 index 0000000000000000000000000000000000000000..c3555b94720c7925e840c95be67b8d4559c7b7e5 GIT binary patch literal 96256 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

6;DNh!4nH!cF?+@Rd@EGa{))?(Z5 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