diff --git a/.env.example b/.env.example index 479a50a..0152884 100644 --- a/.env.example +++ b/.env.example @@ -36,8 +36,6 @@ MAIL_ADMIN=equipe.web@ldc.fr # Sentry SENTRY_LARAVEL_DSN= -LDC_STATUS_CHECKER_API_KEY= - # ADMIN SECURE # - API ENDPOINT (Optional) LDC_WEB_API_ENDPOINT= @@ -45,3 +43,7 @@ LDC_WEB_API_ENDPOINT= LDC_WEB_API_KEY= # - LIST SEPARATED WITH ',' (Optional) LDC_WEB_CIDR_MANUAL_ALLOWED_LIST= + +# GITLAB API +GITLAB_URL= +GITLAB_TOKEN= diff --git a/app/Enums/Users/GitlabUsersEnum.php b/app/Enums/Users/GitlabUsersEnum.php new file mode 100644 index 0000000..5a6d2d3 --- /dev/null +++ b/app/Enums/Users/GitlabUsersEnum.php @@ -0,0 +1,20 @@ +name => "Olivier LEGAT", + ]; +} diff --git a/app/Http/Controllers/Bo/TicketController.php b/app/Http/Controllers/Bo/TicketController.php index 63412cc..c270fe6 100644 --- a/app/Http/Controllers/Bo/TicketController.php +++ b/app/Http/Controllers/Bo/TicketController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\Bo; use App\Enums\Tickets\TicketStatusEnum; use App\Enums\Tickets\TicketTypeEnum; +use App\Enums\Users\GitlabUsersEnum; use App\Events\NotifySubscriptions; use App\Events\TicketStatusChanged; use App\Http\Controllers\Controller; @@ -21,6 +22,7 @@ use App\Models\Message; use App\Models\Site; use App\Models\Ticket; use App\Models\User; +use GrahamCampbell\GitLab\Facades\GitLab; use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; @@ -624,4 +626,82 @@ class TicketController extends Controller ); }); } + + /** + * Create a gitlab issue from a ticket. + * + * @param \App\Models\Ticket $ticket + * @return \Illuminate\Http\RedirectResponse + */ + public function createGitlabIssue(Ticket $ticket) + { + $gitlabRepoId = $ticket->site->gitlab_project_id; + $description = \sprintf("%s
", $ticket->text); + $cLabel = match ($ticket->type) { + TicketTypeEnum::bug => 'c-bug', + TicketTypeEnum::evolution => 'c-feature', + }; + + try { + if (!\is_null($ticket->file)) { + $uploadedFile = GitLab::projects()->uploadFile($gitlabRepoId, $ticket->file); + $description .= $this->formatGitlabFiles($ticket, $uploadedFile, 1); + } + + if (!\is_null($ticket->file2)) { + $uploadedFile2 = GitLab::projects()->uploadFile($gitlabRepoId, $ticket->file2); + $description .= $this->formatGitlabFiles($ticket, $uploadedFile2, 2); + } + + $issue = GitLab::issues()->create($gitlabRepoId, [ + 'title' => 'ts-' . $ticket->id, + 'description' => $description, + 'labels' => \implode(",", [ + 'c-support', + $cLabel + ]), + 'assignee_id' => GitlabUsersEnum::olivier, + ]); + } catch (\Exception $e) { + \report($e); + return back()->with('error', \trans("Une erreur est survenue")); + } catch (\Throwable $e) { + \report($e); + return back()->with('error', \trans("Une erreur est survenue")); + } //end try + + $ticket->gitlab_issue = $issue['web_url']; + $ticket->save(); + + return back()->with( + 'success', + trans("L'issue a été créée sur Gitlab.") + ); + } + + /** + * Format files for Gitlab issues + * + * @param \App\Models\Ticket $ticket + * @param array $uploadedFile + * @param integer $fileNb + * @return string + */ + private function formatGitlabFiles(Ticket $ticket, array $uploadedFile, int $fileNb) + { + if (Str::endsWith($ticket->file, ['jpg', 'png', 'jpeg'])) { + $file = \sprintf( + "![Fichier joint %d](%s)", + $fileNb, + $uploadedFile['url'] + ); + } else { + $file = \sprintf( + '%s', + $uploadedFile['url'], + __('Lien vers le fichier'), + ); + } + return \sprintf("

Fichier %d :
%s
", $fileNb, $file); + } } diff --git a/app/Http/Requests/Bo/Sites/StoreSiteRequest.php b/app/Http/Requests/Bo/Sites/StoreSiteRequest.php index e85e410..44b5a2d 100644 --- a/app/Http/Requests/Bo/Sites/StoreSiteRequest.php +++ b/app/Http/Requests/Bo/Sites/StoreSiteRequest.php @@ -27,7 +27,8 @@ class StoreSiteRequest extends FormRequest return [ 'name' => 'required|string|min:3|max:255', 'users' => 'nullable|array', - 'users.*.id' => 'required|exists:users,id' + 'users.*.id' => 'required|exists:users,id', + 'gitlab_project_id' => 'nullable|unique:sites,gitlab_project_id' ]; } @@ -42,6 +43,7 @@ class StoreSiteRequest extends FormRequest 'name' => trans('Nom du site'), 'users' => trans('Utilisateurs associés au site'), 'users.*.id' => trans('Élément parmis les Utilisateurs associés au site'), + 'gitlab_project_id' => trans('ID du dépôt Gitlab') ]; } } diff --git a/app/Http/Requests/Bo/Sites/UpdateSiteRequest.php b/app/Http/Requests/Bo/Sites/UpdateSiteRequest.php index 2f665be..56899c7 100644 --- a/app/Http/Requests/Bo/Sites/UpdateSiteRequest.php +++ b/app/Http/Requests/Bo/Sites/UpdateSiteRequest.php @@ -4,4 +4,15 @@ namespace App\Http\Requests\Bo\Sites; class UpdateSiteRequest extends StoreSiteRequest { + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return array_merge(parent::rules(), [ + 'gitlab_project_id' => 'nullable|unique:sites,gitlab_project_id,' . $this->route('site')->id . ',id', + ]); + } } diff --git a/app/Models/Site.php b/app/Models/Site.php index 3e005af..d90b579 100644 --- a/app/Models/Site.php +++ b/app/Models/Site.php @@ -7,8 +7,9 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Casts\Attribute; /** - * @property string $name - * @property Brand $brand_id + * @property string $name + * @property integer $gitlab_project_id + * @property Brand $brand_id */ class Site extends Model { @@ -21,6 +22,7 @@ class Site extends Model */ protected $fillable = [ 'name', + 'gitlab_project_id' ]; /** diff --git a/app/Policies/TicketPolicy.php b/app/Policies/TicketPolicy.php index 1b8c828..bcb8074 100644 --- a/app/Policies/TicketPolicy.php +++ b/app/Policies/TicketPolicy.php @@ -3,6 +3,7 @@ namespace App\Policies; use App\Enums\Tickets\TicketStatusEnum; +use App\Enums\Tickets\TicketTypeEnum; use App\Enums\Users\RoleEnum; use App\Models\Ticket; use App\Models\User; @@ -260,4 +261,19 @@ class TicketPolicy return $user->role->equals(RoleEnum::developper) && $ticket->estimation()->exists(); } + + /** + * Determine if the user can create a gitlab issue from a given ticket. + * + * @param \App\Models\User $user + * @param \App\Models\Ticket $ticket + * @return boolean + */ + public function createGitlabIssue(User $user, Ticket $ticket) + { + return $user->role->equals(RoleEnum::developper) + && ($ticket->type->equals(TicketTypeEnum::bug) || $ticket->type->equals(TicketTypeEnum::evolution)) + && !\is_null($ticket->site->gitlab_project_id) + && \is_null($ticket->gitlab_issue); + } } diff --git a/composer.json b/composer.json index 543b3d2..7e0f231 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ "carlos-meneses/laravel-mpdf": "^2.1", "diglactic/laravel-breadcrumbs": "^8.0", "doctrine/dbal": "^3.1", + "graham-campbell/gitlab": "^7.0", "guzzlehttp/guzzle": "^7.2", "laravel-lang/lang": "~8.0", "laravel-validation-rules/colour": "^1.6", @@ -20,7 +21,6 @@ "laravel/tinker": "^2.8", "laravel/ui": "^4.2", "ldc/web-admin-secure-laravel": "^2.0", - "ldc/web-status-checker-laravel": "^1.0", "mews/purifier": "^3.4", "sentry/sentry-laravel": "*", "uwil/k8s-laravel": "^1.2" diff --git a/composer.lock b/composer.lock index 59be3f3..4410ac9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8b8d80affdf1ee455767d5e675bf5fe8", + "content-hash": "4f5fe189b89c5ccc99fc4c7a913a64a6", "packages": [ { "name": "brick/math", @@ -1251,6 +1251,228 @@ ], "time": "2022-02-20T15:07:15+00:00" }, + { + "name": "graham-campbell/bounded-cache", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Bounded-Cache.git", + "reference": "2840f46f38185e610e62af3662dac75ca1877a84" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Bounded-Cache/zipball/2840f46f38185e610e62af3662dac75ca1877a84", + "reference": "2840f46f38185e610e62af3662dac75ca1877a84", + "shasum": "" + }, + "require": { + "php": "^8.0.2", + "psr/simple-cache": "^2.0 || ^3.0" + }, + "require-dev": { + "graham-campbell/analyzer": "^4.0", + "graham-campbell/testbench-core": "^4.0", + "mockery/mockery": "^1.5.1", + "phpunit/phpunit": "^9.6.3 || ^10.0.12" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\BoundedCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "A Bounded TTL PSR-16 Cache Implementation", + "keywords": [ + "Bounded Cache", + "Bounded-Cache", + "Graham Campbell", + "GrahamCampbell", + "bounded", + "cache", + "psr16" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Bounded-Cache/issues", + "source": "https://github.com/GrahamCampbell/Bounded-Cache/tree/v2.1.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/bounded-cache", + "type": "tidelift" + } + ], + "time": "2023-02-25T23:00:30+00:00" + }, + { + "name": "graham-campbell/gitlab", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Laravel-GitLab.git", + "reference": "fb037dedadacb16e4ab75b8bab58b52b703a4e33" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Laravel-GitLab/zipball/fb037dedadacb16e4ab75b8bab58b52b703a4e33", + "reference": "fb037dedadacb16e4ab75b8bab58b52b703a4e33", + "shasum": "" + }, + "require": { + "graham-campbell/bounded-cache": "^1.2 || ^2.0", + "graham-campbell/manager": "^5.0", + "guzzlehttp/guzzle": "^7.5", + "guzzlehttp/psr7": "^2.4", + "illuminate/contracts": "^8.75 || ^9.0 || ^10.0", + "illuminate/support": "^8.75 || ^9.0 || ^10.0", + "m4tthumphrey/php-gitlab-api": "11.9.*", + "php": "^7.4.15 || ^8.0.2", + "symfony/cache": "^5.4 || ^6.0" + }, + "require-dev": { + "graham-campbell/analyzer": "^4.0", + "graham-campbell/testbench": "^6.0", + "mockery/mockery": "^1.5.1", + "phpunit/phpunit": "^9.6.3 || ^10.0.12" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "GrahamCampbell\\GitLab\\GitLabServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "GrahamCampbell\\GitLab\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "GitLab Is A GitLab Bridge For Laravel", + "keywords": [ + "Bridge", + "Graham Campbell", + "GrahamCampbell", + "Laravel GitLab", + "Laravel-GitLab", + "PHP GitLab API", + "framework", + "gitlab", + "gitlab bridge", + "laravel", + "php-gitlab-api" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Laravel-GitLab/issues", + "source": "https://github.com/GrahamCampbell/Laravel-GitLab/tree/v7.0.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/gitlab", + "type": "tidelift" + } + ], + "time": "2023-03-07T11:41:34+00:00" + }, + { + "name": "graham-campbell/manager", + "version": "v5.0.0", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Laravel-Manager.git", + "reference": "f1cf95a0bb11ba086387b8049e0e40b82d01588d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Laravel-Manager/zipball/f1cf95a0bb11ba086387b8049e0e40b82d01588d", + "reference": "f1cf95a0bb11ba086387b8049e0e40b82d01588d", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^8.75 || ^9.0 || ^10.0", + "illuminate/support": "^8.75 || ^9.0 || ^10.0", + "php": "^7.4.15 || ^8.0.2" + }, + "require-dev": { + "graham-campbell/analyzer": "^4.0", + "graham-campbell/testbench-core": "^4.0", + "mockery/mockery": "^1.5.1", + "phpunit/phpunit": "^9.6.3 || ^10.0.12" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\Manager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Manager Provides Some Manager Functionality For Laravel", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Laravel Manager", + "Laravel-Manager", + "connector", + "framework", + "interface", + "laravel", + "manager" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Laravel-Manager/issues", + "source": "https://github.com/GrahamCampbell/Laravel-Manager/tree/v5.0.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/manager", + "type": "tidelift" + } + ], + "time": "2023-02-25T23:53:34+00:00" + }, { "name": "graham-campbell/result-type", "version": "v1.1.1", @@ -2400,113 +2622,6 @@ ], "description": "Restrict access to LDC Network" }, - { - "name": "ldc/web-status-checker", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://lab.s-web.fr/ldc-web/projets/ldc-web-status-checker.git", - "reference": "7ce62449f3eb052de2d7bfa2e32d37d4524d60b0" - }, - "dist": { - "type": "zip", - "url": "https://lab.s-web.fr/api/v4/projects/21/packages/composer/archives/ldc/web-status-checker.zip?sha=7ce62449f3eb052de2d7bfa2e32d37d4524d60b0", - "reference": "7ce62449f3eb052de2d7bfa2e32d37d4524d60b0", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "php": "~7.3|7.4|~8" - }, - "require-dev": { - "slevomat/coding-standard": "^7.0", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "LDC\\WebStatusChecker\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "LDC\\WebStatusChecker\\Tests\\": "tests" - } - }, - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jérémy Munsch", - "email": "jeremy.munsch@ldc.fr", - "homepage": "https://jeremydev.ovh" - } - ], - "description": "Status checker: report status to ldc-web" - }, - { - "name": "ldc/web-status-checker-laravel", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://lab.s-web.fr/ldc-web/projets/ldc-web-status-checker-laravel.git", - "reference": "3918891846f1e8440ba54b23dc47422f005070b9" - }, - "dist": { - "type": "zip", - "url": "https://lab.s-web.fr/api/v4/projects/22/packages/composer/archives/ldc/web-status-checker-laravel.zip?sha=3918891846f1e8440ba54b23dc47422f005070b9", - "reference": "3918891846f1e8440ba54b23dc47422f005070b9", - "shasum": "" - }, - "require": { - "illuminate/support": "~8|~9|~10", - "laravel/framework": "~8|~9|~10", - "ldc/web-status-checker": "^1.1.0", - "php": "~7.3|7.4|~8" - }, - "require-dev": { - "slevomat/coding-standard": "^7.0", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "LDC\\WebStatusCheckerLaravel\\StatusCheckerServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "LDC\\WebStatusCheckerLaravel\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "LDC\\WebStatusCheckerLaravel\\Tests\\": "tests" - } - }, - "scripts": { - "test": [ - "vendor/bin/phpunit" - ], - "post-autoload-dump": [ - "@php ./vendor/bin/testbench package:discover --ansi" - ] - }, - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jérémy Munsch", - "email": "jeremy.munsch@ldc.fr", - "homepage": "https://jeremydev.ovh" - } - ], - "description": "Status checker: report status to ldc-web" - }, { "name": "league/commonmark", "version": "2.4.0", @@ -2899,6 +3014,96 @@ ], "time": "2022-04-17T13:12:02+00:00" }, + { + "name": "m4tthumphrey/php-gitlab-api", + "version": "11.9.1", + "source": { + "type": "git", + "url": "https://github.com/GitLabPHP/Client.git", + "reference": "148ed10609f92e03afbf756e734ee4b76be36832" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GitLabPHP/Client/zipball/148ed10609f92e03afbf756e734ee4b76be36832", + "reference": "148ed10609f92e03afbf756e734ee4b76be36832", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-xml": "*", + "php": "^7.4.15 || ^8.0.2", + "php-http/cache-plugin": "^1.7.5", + "php-http/client-common": "^2.6", + "php-http/discovery": "^1.15", + "php-http/httplug": "^2.3", + "php-http/multipart-stream-builder": "^1.2", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "psr/http-client-implementation": "^1.0", + "psr/http-factory-implementation": "^1.0", + "psr/http-message": "^1.0", + "symfony/options-resolver": "^4.4 || ^5.0 || ^6.0", + "symfony/polyfill-php80": "^1.26" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "guzzlehttp/guzzle": "^7.5", + "http-interop/http-factory-guzzle": "^1.0" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "Gitlab\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Bourigault", + "email": "bourigaultfabien@gmail.com", + "homepage": "https://github.com/fbourigault" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Matt Humphrey", + "email": "matth@windsor-telecom.co.uk", + "homepage": "https://github.com/m4tthumphrey" + }, + { + "name": "Miguel Piedrafita", + "email": "github@miguelpiedrafita.com", + "homepage": "https://github.com/m1guelpf" + } + ], + "description": "GitLab API v4 client for PHP", + "keywords": [ + "api", + "gitlab" + ], + "support": { + "issues": "https://github.com/GitLabPHP/Client/issues", + "source": "https://github.com/GitLabPHP/Client/tree/11.9.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + } + ], + "time": "2023-04-30T19:02:00+00:00" + }, { "name": "mews/purifier", "version": "3.4.0", @@ -3779,6 +3984,60 @@ }, "time": "2020-10-15T08:29:30+00:00" }, + { + "name": "php-http/cache-plugin", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/cache-plugin.git", + "reference": "6bf9fbf66193f61d90c2381b75eb1fa0202fd314" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/cache-plugin/zipball/6bf9fbf66193f61d90c2381b75eb1fa0202fd314", + "reference": "6bf9fbf66193f61d90c2381b75eb1fa0202fd314", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/client-common": "^1.9 || ^2.0", + "php-http/message-factory": "^1.0", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "symfony/options-resolver": "^2.6 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "phpspec/phpspec": "^5.1 || ^6.0 || ^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Client\\Common\\Plugin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "PSR-6 Cache plugin for HTTPlug", + "homepage": "http://httplug.io", + "keywords": [ + "cache", + "http", + "httplug", + "plugin" + ], + "support": { + "issues": "https://github.com/php-http/cache-plugin/issues", + "source": "https://github.com/php-http/cache-plugin/tree/1.8.0" + }, + "time": "2023-04-28T10:56:55+00:00" + }, { "name": "php-http/client-common", "version": "2.7.0", @@ -4107,6 +4366,62 @@ "abandoned": "psr/http-factory", "time": "2023-04-14T14:16:17+00:00" }, + { + "name": "php-http/multipart-stream-builder", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/multipart-stream-builder.git", + "reference": "f5938fd135d9fa442cc297dc98481805acfe2b6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/multipart-stream-builder/zipball/f5938fd135d9fa442cc297dc98481805acfe2b6a", + "reference": "f5938fd135d9fa442cc297dc98481805acfe2b6a", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/discovery": "^1.15", + "psr/http-factory-implementation": "^1.0" + }, + "require-dev": { + "nyholm/psr7": "^1.0", + "php-http/message": "^1.5", + "php-http/message-factory": "^1.0.2", + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Message\\MultipartStream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + } + ], + "description": "A builder class that help you create a multipart stream", + "homepage": "http://php-http.org", + "keywords": [ + "factory", + "http", + "message", + "multipart stream", + "stream" + ], + "support": { + "issues": "https://github.com/php-http/multipart-stream-builder/issues", + "source": "https://github.com/php-http/multipart-stream-builder/tree/1.3.0" + }, + "time": "2023-04-28T14:10:22+00:00" + }, { "name": "php-http/promise", "version": "1.1.0", @@ -5387,6 +5702,178 @@ ], "time": "2023-02-09T10:38:43+00:00" }, + { + "name": "symfony/cache", + "version": "v6.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "d176b97600860df13e851538c2df2ad88e9e5ca9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/d176b97600860df13e851538c2df2ad88e9e5ca9", + "reference": "d176b97600860df13e851538c2df2ad88e9e5ca9", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/cache": "^2.0|^3.0", + "psr/log": "^1.1|^2|^3", + "symfony/cache-contracts": "^2.5|^3", + "symfony/service-contracts": "^2.5|^3", + "symfony/var-exporter": "^6.2.10" + }, + "conflict": { + "doctrine/dbal": "<2.13.1", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/var-dumper": "<5.4" + }, + "provide": { + "psr/cache-implementation": "2.0|3.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0", + "symfony/cache-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/dbal": "^2.13.1|^3.0", + "predis/predis": "^1.1|^2.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/filesystem": "^5.4|^6.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/messenger": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "classmap": [ + "Traits/ValueWrapper.php" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "support": { + "source": "https://github.com/symfony/cache/tree/v6.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-07-27T16:19:14+00:00" + }, + { + "name": "symfony/cache-contracts", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "ad945640ccc0ae6e208bcea7d7de4b39b569896b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/ad945640ccc0ae6e208bcea7d7de4b39b569896b", + "reference": "ad945640ccc0ae6e208bcea7d7de4b39b569896b", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/cache": "^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Cache\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to caching", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/cache-contracts/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, { "name": "symfony/console", "version": "v6.3.0", @@ -7955,6 +8442,80 @@ ], "time": "2023-06-21T12:08:28+00:00" }, + { + "name": "symfony/var-exporter", + "version": "v6.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "3400949782c0cb5b3e73aa64cfd71dde000beccc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/3400949782c0cb5b3e73aa64cfd71dde000beccc", + "reference": "3400949782c0cb5b3e73aa64cfd71dde000beccc", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony/var-dumper": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "lazy-loading", + "proxy", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v6.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-07-26T17:39:03+00:00" + }, { "name": "tijsverkoyen/css-to-inline-styles", "version": "2.2.6", diff --git a/config/gitlab.php b/config/gitlab.php new file mode 100644 index 0000000..6f8f388 --- /dev/null +++ b/config/gitlab.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +return [ + + /** + *-------------------------------------------------------------------------- + * Default Connection Name + *-------------------------------------------------------------------------- + * + * Here you may specify which of the connections below you wish to use as + * your default connection for all work. Of course, you may use many + * connections at once using the manager class. + * + */ + + 'default' => 'main', + + /** + *-------------------------------------------------------------------------- + * GitLab Connections + *-------------------------------------------------------------------------- + * + * Here are each of the connections setup for your application. Example + * configuration has been included, but you may add as many connections as + * you would like. Note that the 4 supported authentication methods are: + * "none", "oauth", "job_token", and "token". + * + */ + + 'connections' => [ + 'main' => [ + 'token' => env('GITLAB_TOKEN'), + 'method' => 'token', + 'url' => env('GITLAB_URL'), + ], + ], + + /** + *-------------------------------------------------------------------------- + * HTTP Cache + *-------------------------------------------------------------------------- + * + * Here are each of the cache configurations setup for your application. + * Only the "illuminate" driver is provided out of the box. Example + * configuration has been included. + * + */ + + 'cache' => [ + + 'main' => [ + 'driver' => 'illuminate', + 'connector' => null, + ], + + 'bar' => [ + 'driver' => 'illuminate', + 'connector' => 'redis', + ], + + ], + +]; diff --git a/database/migrations/2023_08_14_134026_add_gitlab_id_to_sites_table.php b/database/migrations/2023_08_14_134026_add_gitlab_id_to_sites_table.php new file mode 100644 index 0000000..43f46f5 --- /dev/null +++ b/database/migrations/2023_08_14_134026_add_gitlab_id_to_sites_table.php @@ -0,0 +1,36 @@ +unsignedInteger('gitlab_project_id') + ->unique() + ->nullable() + ->comment("ID du dépôt Gitlab") + ->after('name'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down(): void + { + Schema::table('sites', function (Blueprint $table) { + $table->dropColumn('gitlab_project_id'); + }); + } +}; diff --git a/database/migrations/2023_08_14_151531_add_gitlab_issue_to_tickets_table.php b/database/migrations/2023_08_14_151531_add_gitlab_issue_to_tickets_table.php new file mode 100644 index 0000000..cbb42db --- /dev/null +++ b/database/migrations/2023_08_14_151531_add_gitlab_issue_to_tickets_table.php @@ -0,0 +1,35 @@ +string('gitlab_issue') + ->nullable() + ->comment("URL de l'issue Gitlab") + ->after('is_internal'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down(): void + { + Schema::table('tickets', function (Blueprint $table) { + $table->dropColumn('gitlab_issue'); + }); + } +}; diff --git a/resources/lang/fr/validation.php b/resources/lang/fr/validation.php index 825dbe1..b4f16c9 100644 --- a/resources/lang/fr/validation.php +++ b/resources/lang/fr/validation.php @@ -155,6 +155,7 @@ return [ 'excerpt' => 'extrait', 'firstname' => 'prénom', 'gender' => 'genre', + 'gitlab_project_id' => 'id du dépôt Gitlab', 'hour' => 'heure', 'invoiced_to_id' => 'Entité à facturer', 'label' => 'label', diff --git a/resources/views/bo/pages/sites/form-inputs.blade.php b/resources/views/bo/pages/sites/form-inputs.blade.php index e183969..fa9a69d 100644 --- a/resources/views/bo/pages/sites/form-inputs.blade.php +++ b/resources/views/bo/pages/sites/form-inputs.blade.php @@ -59,6 +59,34 @@ + {{-- GITLAB_PROJECT_ID --}} +
+
+ {{ Str::ucfirst(__('validation.attributes.gitlab_project_id')) }} +
+
+ @include('bo.partials.inputs.int-number', [ + 'id' => 'siteGitlabProject', + 'label' => __(':field du :model', [ + 'field' => Str::ucfirst(__('validation.attributes.gitlab_project_id')), + 'model' => Str::singular(__('models.classes.sites')), + ]), + 'name' => 'gitlab_project_id', + 'required' => true, + 'model' => $siteModel ?? null, + 'helper' => __('validation.integer', [ + 'attribute' => __(':field du :model', [ + 'field' => Str::ucfirst(__('validation.attributes.gitlab_project_id')), + 'model' => Str::singular(__('models.classes.sites')), + ]), + ]), + 'step' => 1, + 'min' => 1 + ]) +
+
+
+
@push('scripts') diff --git a/resources/views/bo/pages/tickets/show.blade.php b/resources/views/bo/pages/tickets/show.blade.php index f448edd..8fa0819 100644 --- a/resources/views/bo/pages/tickets/show.blade.php +++ b/resources/views/bo/pages/tickets/show.blade.php @@ -256,4 +256,18 @@ @endif +@can('createGitlabIssue', $ticket) +
+ @csrf + +
+@else + @if (!\is_null($ticket->gitlab_issue)) +
+

+ {{ __("Lien vers l'issue Gitlab : ")}} + {{ __("Ouvrir") }} +

+ @endif +@endcan @endsection diff --git a/routes/web-bo.php b/routes/web-bo.php index 9d83548..241f6fd 100644 --- a/routes/web-bo.php +++ b/routes/web-bo.php @@ -90,7 +90,10 @@ Route::middleware('admin-secure') // * TICKETS Route::get('/tickets/json/paginate', [TicketController::class, 'jsonPaginate']) - ->name('tickets.json-paginate'); + ->name('tickets.json-paginate'); + Route::post('/ticket/{ticket}/create-issue', [TicketController::class, 'createGitlabIssue']) + ->middleware('can:createGitlabIssue,ticket') + ->name('ticket.create-issue'); // * SCHEDULE Route::prefix('/schedule')