From fe96a00b8259a035cfaf77014bd384190fbd1e82 Mon Sep 17 00:00:00 2001 From: James Brooks Date: Fri, 14 Oct 2016 08:03:19 +0100 Subject: [PATCH] Incident templates cleanup (#2182) Clean up Incident Templates, supply incident array to them by default --- .../Incident/ReportIncidentCommand.php | 10 +- .../Incident/UpdateIncidentCommand.php | 4 +- .../Incident/ReportIncidentCommandHandler.php | 67 +++++++------ .../Incident/UpdateIncidentCommandHandler.php | 63 ++++++++----- .../ReportIncidentUpdateCommandHandler.php | 2 +- .../Controllers/Api/IncidentController.php | 4 +- .../Dashboard/IncidentController.php | 4 +- app/Models/IncidentTemplate.php | 23 +++-- composer.json | 2 +- composer.lock | 93 +++---------------- config/app.php | 1 - tests/Api/IncidentTest.php | 10 +- .../Incident/ReportIncidentCommandTest.php | 2 +- .../Incident/UpdateIncidentCommandTest.php | 2 +- 14 files changed, 127 insertions(+), 160 deletions(-) diff --git a/app/Bus/Commands/Incident/ReportIncidentCommand.php b/app/Bus/Commands/Incident/ReportIncidentCommand.php index 67158bfc9aa1..bc42298b6e15 100644 --- a/app/Bus/Commands/Incident/ReportIncidentCommand.php +++ b/app/Bus/Commands/Incident/ReportIncidentCommand.php @@ -11,6 +11,12 @@ namespace CachetHQ\Cachet\Bus\Commands\Incident; +/** + * This is the report incident command. + * + * @author Joseph Cohen + * @author James Brooks + */ final class ReportIncidentCommand { /** @@ -121,11 +127,11 @@ final class ReportIncidentCommand * @param bool $stickied * @param string|null $incident_date * @param string|null $template - * @param array|null $template_vars + * @param array $template_vars * * @return void */ - public function __construct($name, $status, $message, $visible, $component_id, $component_status, $notify, $stickied, $incident_date, $template, array $template_vars = null) + public function __construct($name, $status, $message, $visible, $component_id, $component_status, $notify, $stickied, $incident_date, $template, array $template_vars = []) { $this->name = $name; $this->status = $status; diff --git a/app/Bus/Commands/Incident/UpdateIncidentCommand.php b/app/Bus/Commands/Incident/UpdateIncidentCommand.php index 928e037a1e44..3dcd47573bda 100644 --- a/app/Bus/Commands/Incident/UpdateIncidentCommand.php +++ b/app/Bus/Commands/Incident/UpdateIncidentCommand.php @@ -130,11 +130,11 @@ final class UpdateIncidentCommand * @param bool $stickied * @param string|null $incident_date * @param string|null $template - * @param array|null $template_vars + * @param array $template_vars * * @return void */ - public function __construct(Incident $incident, $name, $status, $message, $visible, $component_id, $component_status, $notify, $stickied, $incident_date, $template, array $template_vars = null) + public function __construct(Incident $incident, $name, $status, $message, $visible, $component_id, $component_status, $notify, $stickied, $incident_date, $template, array $template_vars = []) { $this->incident = $incident; $this->name = $name; diff --git a/app/Bus/Handlers/Commands/Incident/ReportIncidentCommandHandler.php b/app/Bus/Handlers/Commands/Incident/ReportIncidentCommandHandler.php index cae916339456..424f42b66529 100644 --- a/app/Bus/Handlers/Commands/Incident/ReportIncidentCommandHandler.php +++ b/app/Bus/Handlers/Commands/Incident/ReportIncidentCommandHandler.php @@ -11,14 +11,15 @@ namespace CachetHQ\Cachet\Bus\Handlers\Commands\Incident; +use CachetHQ\Cachet\Bus\Commands\Component\UpdateComponentCommand; use CachetHQ\Cachet\Bus\Commands\Incident\ReportIncidentCommand; use CachetHQ\Cachet\Bus\Events\Incident\IncidentWasReportedEvent; use CachetHQ\Cachet\Dates\DateFactory; use CachetHQ\Cachet\Models\Component; use CachetHQ\Cachet\Models\Incident; use CachetHQ\Cachet\Models\IncidentTemplate; -use Twig_Loader_String; -use TwigBridge\Bridge; +use Twig_Environment; +use Twig_Loader_Array; /** * This is the report incident command handler. @@ -34,25 +35,16 @@ class ReportIncidentCommandHandler */ protected $dates; - /** - * The twig bridge instance. - * - * @var \TwigBridge\Bridge - */ - protected $twig; - /** * Create a new report incident command handler instance. * * @param \CachetHQ\Cachet\Dates\DateFactory $dates - * @param \TwigBridge\Bridge $twig * * @return void */ - public function __construct(DateFactory $dates, Bridge $twig) + public function __construct(DateFactory $dates) { $this->dates = $dates; - $this->twig = $twig; } /** @@ -71,8 +63,8 @@ public function handle(ReportIncidentCommand $command) 'stickied' => $command->stickied, ]; - if ($command->template) { - $data['message'] = $this->parseIncidentTemplate($command->template, $command->template_vars); + if ($template = IncidentTemplate::where('slug', $command->template)->first()) { + $data['message'] = $this->parseTemplate($template, $command); } else { $data['message'] = $command->message; } @@ -94,10 +86,17 @@ public function handle(ReportIncidentCommand $command) $incident = Incident::create($data); // Update the component. - if ($command->component_id) { - Component::find($command->component_id)->update([ - 'status' => $command->component_status, - ]); + if ($component = Component::find($command->component_id)) { + dispatch(new UpdateComponentCommand( + Component::find($command->component_id), + null, + null, + $command->component_status, + null, + null, + null, + null + )); } $incident->notify = (bool) $command->notify; @@ -110,20 +109,30 @@ public function handle(ReportIncidentCommand $command) /** * Compiles an incident template into an incident message. * - * @param string $templateSlug - * @param array $vars + * @param \CachetHQ\Cachet\Models\IncidentTemplate $template + * @param \CachetHQ\Cachet\Bus\Commands\Incident\ReportIncidentCommand $command * * @return string */ - protected function parseIncidentTemplate($templateSlug, $vars) + protected function parseTemplate(IncidentTemplate $template, ReportIncidentCommand $command) { - if ($vars === null) { - $vars = []; - } - - $this->twig->setLoader(new Twig_Loader_String()); - $template = IncidentTemplate::forSlug($templateSlug)->first(); - - return $this->twig->render($template->template, $vars); + $env = new Twig_Environment(new Twig_Loader_Array([])); + $template = $env->createTemplate($template->template); + + $vars = array_merge($command->template_vars, [ + 'incident' => [ + 'name' => $command->name, + 'status' => $command->status, + 'message' => $command->message, + 'visible' => $command->visible, + 'notify' => $command->notify, + 'stickied' => $command->stickied, + 'incident_date' => $command->incident_date, + 'component' => Component::find($command->component_id) ?: null, + 'component_status' => $command->component_status, + ], + ]); + + return $template->render($vars); } } diff --git a/app/Bus/Handlers/Commands/Incident/UpdateIncidentCommandHandler.php b/app/Bus/Handlers/Commands/Incident/UpdateIncidentCommandHandler.php index 8001cf6ae14d..55d1323f9ecb 100644 --- a/app/Bus/Handlers/Commands/Incident/UpdateIncidentCommandHandler.php +++ b/app/Bus/Handlers/Commands/Incident/UpdateIncidentCommandHandler.php @@ -11,14 +11,15 @@ namespace CachetHQ\Cachet\Bus\Handlers\Commands\Incident; +use CachetHQ\Cachet\Bus\Commands\Component\UpdateComponentCommand; use CachetHQ\Cachet\Bus\Commands\Incident\UpdateIncidentCommand; use CachetHQ\Cachet\Bus\Events\Incident\IncidentWasUpdatedEvent; use CachetHQ\Cachet\Dates\DateFactory; use CachetHQ\Cachet\Models\Component; use CachetHQ\Cachet\Models\Incident; use CachetHQ\Cachet\Models\IncidentTemplate; -use Twig_Loader_String; -use TwigBridge\Bridge; +use Twig_Environment; +use Twig_Loader_Array; /** * This is the update incident command handler. @@ -34,25 +35,16 @@ class UpdateIncidentCommandHandler */ protected $dates; - /** - * The twig bridge instance. - * - * @var \TwigBridge\Bridge - */ - protected $twig; - /** * Create a new update incident command handler instance. * * @param \CachetHQ\Cachet\Dates\DateFactory $dates - * @param \TwigBridge\Bridge $twig * * @return void */ - public function __construct(DateFactory $dates, Bridge $twig) + public function __construct(DateFactory $dates) { $this->dates = $dates; - $this->twig = $twig; } /** @@ -64,8 +56,8 @@ public function __construct(DateFactory $dates, Bridge $twig) */ public function handle(UpdateIncidentCommand $command) { - if ($command->template) { - $command->message = $this->parseIncidentTemplate($command->template, $command->template_vars); + if ($template = IncidentTemplate::where('slug', $command->template)->first()) { + $command->message = $this->parseTemplate($template, $command); } $incident = $command->incident; @@ -82,10 +74,17 @@ public function handle(UpdateIncidentCommand $command) } // Update the component. - if ($command->component_id) { - Component::find($command->component_id)->update([ - 'status' => $command->component_status, - ]); + if ($component = Component::find($command->component_id)) { + dispatch(new UpdateComponentCommand( + Component::find($command->component_id), + null, + null, + $command->component_status, + null, + null, + null, + null + )); } event(new IncidentWasUpdatedEvent($incident)); @@ -121,16 +120,30 @@ protected function filter(UpdateIncidentCommand $command) /** * Compiles an incident template into an incident message. * - * @param string $templateSlug - * @param array $vars + * @param \CachetHQ\Cachet\Models\IncidentTemplate $template + * @param \CachetHQ\Cachet\Bus\Commands\Incident\UpdateIncidentCommand $command * * @return string */ - protected function parseIncidentTemplate($templateSlug, $vars) + protected function parseTemplate(IncidentTemplate $template, UpdateIncidentCommand $command) { - $this->twig->setLoader(new Twig_Loader_String()); - $template = IncidentTemplate::forSlug($templateSlug)->first(); - - return $this->twig->render($template->template, $vars); + $env = new Twig_Environment(new Twig_Loader_Array([])); + $template = $env->createTemplate($template->template); + + $vars = array_merge($command->template_vars, [ + 'incident' => [ + 'name' => $command->name, + 'status' => $command->status, + 'message' => $command->message, + 'visible' => $command->visible, + 'notify' => $command->notify, + 'stickied' => $command->stickied, + 'incident_date' => $command->incident_date, + 'component' => Component::find($command->component_id) ?: null, + 'component_status' => $command->component_status, + ], + ]); + + return $template->render($vars); } } diff --git a/app/Bus/Handlers/Commands/IncidentUpdate/ReportIncidentUpdateCommandHandler.php b/app/Bus/Handlers/Commands/IncidentUpdate/ReportIncidentUpdateCommandHandler.php index c0c22ea853e2..3ede0f6e73c9 100644 --- a/app/Bus/Handlers/Commands/IncidentUpdate/ReportIncidentUpdateCommandHandler.php +++ b/app/Bus/Handlers/Commands/IncidentUpdate/ReportIncidentUpdateCommandHandler.php @@ -55,7 +55,7 @@ public function handle(ReportIncidentUpdateCommand $command) null, null, null, - null + [] )); event(new IncidentUpdateWasReportedEvent($update)); diff --git a/app/Http/Controllers/Api/IncidentController.php b/app/Http/Controllers/Api/IncidentController.php index 0d7c8993c682..2d843710c556 100644 --- a/app/Http/Controllers/Api/IncidentController.php +++ b/app/Http/Controllers/Api/IncidentController.php @@ -78,7 +78,7 @@ public function postIncidents() Binput::get('stickied', false), Binput::get('created_at'), Binput::get('template'), - Binput::get('vars') + Binput::get('vars', []) )); } catch (QueryException $e) { throw new BadRequestHttpException(); @@ -109,7 +109,7 @@ public function putIncident(Incident $incident) Binput::get('stickied', false), Binput::get('created_at'), Binput::get('template'), - Binput::get('vars') + Binput::get('vars', []) )); } catch (QueryException $e) { throw new BadRequestHttpException(); diff --git a/app/Http/Controllers/Dashboard/IncidentController.php b/app/Http/Controllers/Dashboard/IncidentController.php index 9a0091ce0dd7..b1101603de89 100644 --- a/app/Http/Controllers/Dashboard/IncidentController.php +++ b/app/Http/Controllers/Dashboard/IncidentController.php @@ -135,7 +135,7 @@ public function createIncidentAction() Binput::get('stickied', false), Binput::get('created_at'), null, - null + [] )); } catch (ValidationException $e) { return cachet_redirect('dashboard.incidents.create') @@ -261,7 +261,7 @@ public function editIncidentAction(Incident $incident) Binput::get('stickied', false), Binput::get('created_at'), null, - null + [] )); } catch (ValidationException $e) { return cachet_redirect('dashboard.incidents.edit', ['id' => $incident->id]) diff --git a/app/Models/IncidentTemplate.php b/app/Models/IncidentTemplate.php index bec5d4d34a32..b5b9bf51c101 100644 --- a/app/Models/IncidentTemplate.php +++ b/app/Models/IncidentTemplate.php @@ -12,7 +12,6 @@ namespace CachetHQ\Cachet\Models; use AltThree\Validator\ValidatingTrait; -use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; @@ -27,6 +26,7 @@ class IncidentTemplate extends Model */ protected $casts = [ 'name' => 'string', + 'slug' => 'string', 'template' => 'string', ]; @@ -35,7 +35,7 @@ class IncidentTemplate extends Model * * @var string[] */ - protected $fillable = ['name', 'template']; + protected $fillable = ['name', 'slug', 'template']; /** * The validation rules. @@ -43,8 +43,9 @@ class IncidentTemplate extends Model * @var string[] */ public $rules = [ - 'name' => 'required', - 'template' => 'required', + 'name' => 'required|string', + 'slug' => 'string', + 'template' => 'required|string', ]; /** @@ -55,20 +56,24 @@ public static function boot() parent::boot(); self::saving(function ($template) { - $template->slug = Str::slug($template->name); + if (!$template->slug) { + $template->slug = Str::slug($template->name); + } }); } /** * Finds a template by the slug. * - * @param \Illuminate\Database\Query\Builder $query - * @param string $slug + * @param string $slug + * @param string[] $columns * * @return \Illuminate\Database\Query\Builder */ - public function scopeForSlug(Builder $query, $slug) + public static function forSlug($slug, $columns = ['*']) { - return $query->where('slug', $slug); + $template = static::where('slug', $slug)->firstOrFail($columns); + + return $template; } } diff --git a/composer.json b/composer.json index e47634d2321a..44047acc7c2c 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ "mccool/laravel-auto-presenter": "^4.3", "pragmarx/google2fa": "^0.7.1", "predis/predis": "^1.1", - "rcrowe/twigbridge": "^0.9.2", + "twig/twig": "^2.0.0", "roumen/feed": "^2.10.4" }, "require-dev": { diff --git a/composer.lock b/composer.lock index b81d15f106bd..686391bf3510 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "beb947157999db1d55d9af092dd81f37", - "content-hash": "89a23d2b2505160bda9ead17b9b0c0d4", + "hash": "5b4008d015b0c722e137bd32d3b04054", + "content-hash": "72e88a7089a1b4f00cb2f25dcffbdd74", "packages": [ { "name": "alt-three/badger", @@ -325,16 +325,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.19.13", + "version": "3.19.14", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "57b0efed8fcf5d8c854bc1c26cf4a685af9108d9" + "reference": "2d0c88883dac2f8dd21825b51ef1f04e04073f8f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/57b0efed8fcf5d8c854bc1c26cf4a685af9108d9", - "reference": "57b0efed8fcf5d8c854bc1c26cf4a685af9108d9", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/2d0c88883dac2f8dd21825b51ef1f04e04073f8f", + "reference": "2d0c88883dac2f8dd21825b51ef1f04e04073f8f", "shasum": "" }, "require": { @@ -401,7 +401,7 @@ "s3", "sdk" ], - "time": "2016-10-06 21:17:44" + "time": "2016-10-12 21:32:40" }, { "name": "backup-manager/backup-manager", @@ -2957,70 +2957,6 @@ ], "time": "2016-03-09 05:03:14" }, - { - "name": "rcrowe/twigbridge", - "version": "v0.9.3", - "source": { - "type": "git", - "url": "https://github.com/rcrowe/TwigBridge.git", - "reference": "6226d33331bbb1cdf64593a786f7efd1670200a7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/rcrowe/TwigBridge/zipball/6226d33331bbb1cdf64593a786f7efd1670200a7", - "reference": "6226d33331bbb1cdf64593a786f7efd1670200a7", - "shasum": "" - }, - "require": { - "illuminate/support": "5.0.*|5.1.*|5.2.*|5.3.*", - "illuminate/view": "5.0.*|5.1.*|5.2.*|5.3.*", - "php": ">=5.4.0", - "twig/twig": "~1.15|~2.0" - }, - "require-dev": { - "laravel/framework": "5.0.*", - "mockery/mockery": "0.9.*", - "phpunit/phpunit": "~4.0", - "satooshi/php-coveralls": "~0.6", - "squizlabs/php_codesniffer": "~1.5" - }, - "suggest": { - "laravelcollective/html": "For bringing back html/form in Laravel 5.x", - "twig/extensions": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.10-dev" - } - }, - "autoload": { - "psr-4": { - "TwigBridge\\": "src", - "TwigBridge\\Tests\\": "tests" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Barry vd. Heuvel", - "email": "barryvdh@gmail.com" - }, - { - "name": "Rob Crowe", - "email": "hello@vivalacrowe.com" - } - ], - "description": "Adds the power of Twig to Laravel", - "keywords": [ - "laravel", - "twig" - ], - "time": "2016-05-01 16:43:38" - }, { "name": "roumen/feed", "version": "v2.10.4", @@ -4057,20 +3993,21 @@ }, { "name": "twig/twig", - "version": "v1.26.1", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "a09d8ee17ac1cfea29ed60c83960ad685c6a898d" + "reference": "907366d05379156152bcb1862931a1687be71200" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/a09d8ee17ac1cfea29ed60c83960ad685c6a898d", - "reference": "a09d8ee17ac1cfea29ed60c83960ad685c6a898d", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/907366d05379156152bcb1862931a1687be71200", + "reference": "907366d05379156152bcb1862931a1687be71200", "shasum": "" }, "require": { - "php": ">=5.2.7" + "php": ">=5.5", + "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { "symfony/debug": "~2.7", @@ -4079,7 +4016,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.26-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -4114,7 +4051,7 @@ "keywords": [ "templating" ], - "time": "2016-10-05 18:57:41" + "time": "2016-10-05 18:16:59" }, { "name": "vlucas/phpdotenv", diff --git a/config/app.php b/config/app.php index a1f3fb811c98..983b527ac60e 100644 --- a/config/app.php +++ b/config/app.php @@ -175,7 +175,6 @@ 'McCool\LaravelAutoPresenter\AutoPresenterServiceProvider', 'PragmaRX\Google2FA\Vendor\Laravel\ServiceProvider', 'Roumen\Feed\FeedServiceProvider', - 'TwigBridge\ServiceProvider', /* * Application Service Providers... diff --git a/tests/Api/IncidentTest.php b/tests/Api/IncidentTest.php index dfd260a89e70..dea3d3d79d8e 100644 --- a/tests/Api/IncidentTest.php +++ b/tests/Api/IncidentTest.php @@ -130,20 +130,18 @@ public function testPutIncident() public function testPutIncidentWithTemplate() { $this->beUser(); - $template = factory('CachetHQ\Cachet\Models\IncidentTemplate')->create(); + $template = factory('CachetHQ\Cachet\Models\IncidentTemplate')->create([ + 'template' => 'Hello there this is a foo in my {{ incident.name }}!', + ]); $component = factory('CachetHQ\Cachet\Models\Incident')->create(); $this->put('/api/v1/incidents/1', [ 'name' => 'Foo', 'template' => $template->slug, - 'vars' => [ - 'name' => 'Foo', - 'message' => 'Hello there this is a foo!', - ], ]); $this->seeJson([ 'name' => 'Foo', - 'message' => "Name: Foo,\nMessage: Hello there this is a foo!", + 'message' => 'Hello there this is a foo in my Foo!', ]); $this->assertResponseOk(); } diff --git a/tests/Bus/Commands/Incident/ReportIncidentCommandTest.php b/tests/Bus/Commands/Incident/ReportIncidentCommandTest.php index 09ac5c4c114b..6cffe52cb96d 100644 --- a/tests/Bus/Commands/Incident/ReportIncidentCommandTest.php +++ b/tests/Bus/Commands/Incident/ReportIncidentCommandTest.php @@ -39,7 +39,7 @@ protected function getObjectAndParams() 'stickied' => false, 'incident_date' => null, 'template' => null, - 'template_vars' => null, + 'template_vars' => [], ]; $object = new ReportIncidentCommand( diff --git a/tests/Bus/Commands/Incident/UpdateIncidentCommandTest.php b/tests/Bus/Commands/Incident/UpdateIncidentCommandTest.php index 1957dea2158b..0294eb56f6d3 100644 --- a/tests/Bus/Commands/Incident/UpdateIncidentCommandTest.php +++ b/tests/Bus/Commands/Incident/UpdateIncidentCommandTest.php @@ -41,7 +41,7 @@ protected function getObjectAndParams() 'stickied' => false, 'incident_date' => null, 'template' => null, - 'template_vars' => null, + 'template_vars' => [], ]; $object = new UpdateIncidentCommand(