@@ -96,6 +96,13 @@ final class CreateIncidentCommand
|
|||||||
*/
|
*/
|
||||||
public $template_vars;
|
public $template_vars;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Meta key/value pairs.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $meta = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The validation rules.
|
* The validation rules.
|
||||||
*
|
*
|
||||||
@@ -112,6 +119,7 @@ final class CreateIncidentCommand
|
|||||||
'stickied' => 'required|bool',
|
'stickied' => 'required|bool',
|
||||||
'occurred_at' => 'nullable|string',
|
'occurred_at' => 'nullable|string',
|
||||||
'template' => 'nullable|string',
|
'template' => 'nullable|string',
|
||||||
|
'meta' => 'required|array',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -128,10 +136,11 @@ final class CreateIncidentCommand
|
|||||||
* @param string|null $occurred_at
|
* @param string|null $occurred_at
|
||||||
* @param string|null $template
|
* @param string|null $template
|
||||||
* @param array $template_vars
|
* @param array $template_vars
|
||||||
|
* @param array $meta
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct($name, $status, $message, $visible, $component_id, $component_status, $notify, $stickied, $occurred_at, $template, array $template_vars = [])
|
public function __construct($name, $status, $message, $visible, $component_id, $component_status, $notify, $stickied, $occurred_at, $template, array $template_vars = [], $meta = [])
|
||||||
{
|
{
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->status = $status;
|
$this->status = $status;
|
||||||
@@ -144,5 +153,6 @@ final class CreateIncidentCommand
|
|||||||
$this->occurred_at = $occurred_at;
|
$this->occurred_at = $occurred_at;
|
||||||
$this->template = $template;
|
$this->template = $template;
|
||||||
$this->template_vars = $template_vars;
|
$this->template_vars = $template_vars;
|
||||||
|
$this->meta = $meta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ use CachetHQ\Cachet\Bus\Exceptions\Incident\InvalidIncidentTimestampException;
|
|||||||
use CachetHQ\Cachet\Models\Component;
|
use CachetHQ\Cachet\Models\Component;
|
||||||
use CachetHQ\Cachet\Models\Incident;
|
use CachetHQ\Cachet\Models\Incident;
|
||||||
use CachetHQ\Cachet\Models\IncidentTemplate;
|
use CachetHQ\Cachet\Models\IncidentTemplate;
|
||||||
|
use CachetHQ\Cachet\Models\Meta;
|
||||||
use CachetHQ\Cachet\Services\Dates\DateFactory;
|
use CachetHQ\Cachet\Services\Dates\DateFactory;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Contracts\Auth\Guard;
|
use Illuminate\Contracts\Auth\Guard;
|
||||||
@@ -100,6 +101,18 @@ class CreateIncidentCommandHandler
|
|||||||
// Create the incident
|
// Create the incident
|
||||||
$incident = Incident::create($data);
|
$incident = Incident::create($data);
|
||||||
|
|
||||||
|
// Store any meta?
|
||||||
|
if ($meta = $command->meta) {
|
||||||
|
foreach ($meta as $key => $value) {
|
||||||
|
Meta::create([
|
||||||
|
'key' => $key,
|
||||||
|
'value' => $value,
|
||||||
|
'meta_type' => 'incidents',
|
||||||
|
'meta_id' => $incident->id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update the component.
|
// Update the component.
|
||||||
if ($component = Component::find($command->component_id)) {
|
if ($component = Component::find($command->component_id)) {
|
||||||
dispatch(new UpdateComponentCommand(
|
dispatch(new UpdateComponentCommand(
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace CachetHQ\Cachet\Foundation\Providers;
|
|||||||
use AltThree\Bus\Dispatcher;
|
use AltThree\Bus\Dispatcher;
|
||||||
use CachetHQ\Cachet\Bus\Middleware\UseDatabaseTransactions;
|
use CachetHQ\Cachet\Bus\Middleware\UseDatabaseTransactions;
|
||||||
use CachetHQ\Cachet\Services\Dates\DateFactory;
|
use CachetHQ\Cachet\Services\Dates\DateFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
@@ -42,6 +43,14 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
Str::macro('canonicalize', function ($url) {
|
Str::macro('canonicalize', function ($url) {
|
||||||
return preg_replace('/([^\/])$/', '$1/', $url);
|
return preg_replace('/([^\/])$/', '$1/', $url);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Relation::morphMap([
|
||||||
|
'components' => \CachetHQ\Cachet\Models\Component::class,
|
||||||
|
'incidents' => \CachetHQ\Cachet\Models\Incident::class,
|
||||||
|
'metrics' => \CachetHQ\Cachet\Models\Metric::class,
|
||||||
|
'schedules' => \CachetHQ\Cachet\Models\Schedule::class,
|
||||||
|
'subscriber' => \CachetHQ\Cachet\Models\Subscriber::class,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -78,7 +78,8 @@ class IncidentController extends AbstractApiController
|
|||||||
Binput::get('stickied', false),
|
Binput::get('stickied', false),
|
||||||
Binput::get('occurred_at'),
|
Binput::get('occurred_at'),
|
||||||
Binput::get('template'),
|
Binput::get('template'),
|
||||||
Binput::get('vars', [])
|
Binput::get('vars', []),
|
||||||
|
Binput::get('meta', [])
|
||||||
));
|
));
|
||||||
} catch (QueryException $e) {
|
} catch (QueryException $e) {
|
||||||
throw new BadRequestHttpException();
|
throw new BadRequestHttpException();
|
||||||
|
|||||||
@@ -134,6 +134,16 @@ class Component extends Model implements HasPresenter
|
|||||||
return $this->hasMany(Incident::class, 'component_id', 'id');
|
return $this->hasMany(Incident::class, 'component_id', 'id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the meta relation.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
|
*/
|
||||||
|
public function meta()
|
||||||
|
{
|
||||||
|
return $this->morphMany(Meta::class, 'meta');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the tags relation.
|
* Get the tags relation.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -145,7 +145,10 @@ class Incident extends Model implements HasPresenter
|
|||||||
*
|
*
|
||||||
* @var string[]
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
protected $with = ['updates'];
|
protected $with = [
|
||||||
|
'meta',
|
||||||
|
'updates',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the component relation.
|
* Get the component relation.
|
||||||
@@ -157,6 +160,16 @@ class Incident extends Model implements HasPresenter
|
|||||||
return $this->belongsTo(Component::class, 'component_id', 'id');
|
return $this->belongsTo(Component::class, 'component_id', 'id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the meta relation.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
|
*/
|
||||||
|
public function meta()
|
||||||
|
{
|
||||||
|
return $this->morphMany(Meta::class, 'meta');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the updates relation.
|
* Get the updates relation.
|
||||||
*
|
*
|
||||||
|
|||||||
80
app/Models/Meta.php
Normal file
80
app/Models/Meta.php
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Cachet.
|
||||||
|
*
|
||||||
|
* (c) Alt Three Services Limited
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace CachetHQ\Cachet\Models;
|
||||||
|
|
||||||
|
use AltThree\Validator\ValidatingTrait;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the meta model class.
|
||||||
|
*
|
||||||
|
* @author James Brooks <james@alt-three.com>
|
||||||
|
*/
|
||||||
|
class Meta extends Model
|
||||||
|
{
|
||||||
|
use ValidatingTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be casted to native types.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
protected $casts = [
|
||||||
|
'id' => 'int',
|
||||||
|
'key' => 'string',
|
||||||
|
'value' => 'json',
|
||||||
|
'meta_id' => 'int',
|
||||||
|
'meta_type' => 'string',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fillable properties.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'key',
|
||||||
|
'value',
|
||||||
|
'meta_id',
|
||||||
|
'meta_type',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The validation rules.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
public $rules = [
|
||||||
|
'id' => 'nullable|int|min:1',
|
||||||
|
'key' => 'required|string',
|
||||||
|
'value' => 'nullable',
|
||||||
|
'meta_id' => 'required|int',
|
||||||
|
'meta_type' => 'required|string',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The table associated with the model.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $table = 'meta';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the owning meta models.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||||
|
*/
|
||||||
|
public function meta()
|
||||||
|
{
|
||||||
|
return $this->morphTo();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -165,6 +165,16 @@ class Metric extends Model implements HasPresenter
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the meta relation.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
|
*/
|
||||||
|
public function meta()
|
||||||
|
{
|
||||||
|
return $this->morphMany(Meta::class, 'meta');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the points relation.
|
* Get the points relation.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -131,6 +131,26 @@ class Schedule extends Model implements HasPresenter
|
|||||||
*/
|
*/
|
||||||
protected $with = ['components'];
|
protected $with = ['components'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the components relation.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
|
*/
|
||||||
|
public function components()
|
||||||
|
{
|
||||||
|
return $this->hasMany(ScheduleComponent::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the meta relation.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
|
*/
|
||||||
|
public function meta()
|
||||||
|
{
|
||||||
|
return $this->morphMany(Meta::class, 'meta');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scopes schedules to those in the future.
|
* Scopes schedules to those in the future.
|
||||||
*
|
*
|
||||||
@@ -155,16 +175,6 @@ class Schedule extends Model implements HasPresenter
|
|||||||
return $query->where('status', '<', self::COMPLETE)->where('scheduled_at', '<=', Carbon::now());
|
return $query->where('status', '<', self::COMPLETE)->where('scheduled_at', '<=', Carbon::now());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the components relation.
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
|
||||||
*/
|
|
||||||
public function components()
|
|
||||||
{
|
|
||||||
return $this->hasMany(ScheduleComponent::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the presenter class.
|
* Get the presenter class.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -90,6 +90,16 @@ class Subscriber extends Model implements HasPresenter
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the meta relation.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||||
|
*/
|
||||||
|
public function meta()
|
||||||
|
{
|
||||||
|
return $this->morphMany(Meta::class, 'meta');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the subscriptions relation.
|
* Get the subscriptions relation.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -279,6 +279,16 @@ class IncidentPresenter extends BasePresenter implements Arrayable
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the meta in a key value pair.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function meta()
|
||||||
|
{
|
||||||
|
return $this->wrappedObject->meta->pluck('value', 'key')->all();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the presenter instance to an array.
|
* Convert the presenter instance to an array.
|
||||||
*
|
*
|
||||||
@@ -294,6 +304,7 @@ class IncidentPresenter extends BasePresenter implements Arrayable
|
|||||||
'latest_icon' => $this->latest_icon(),
|
'latest_icon' => $this->latest_icon(),
|
||||||
'permalink' => $this->permalink(),
|
'permalink' => $this->permalink(),
|
||||||
'duration' => $this->duration(),
|
'duration' => $this->duration(),
|
||||||
|
'meta' => $this->meta(),
|
||||||
'occurred_at' => $this->occurred_at(),
|
'occurred_at' => $this->occurred_at(),
|
||||||
'created_at' => $this->created_at(),
|
'created_at' => $this->created_at(),
|
||||||
'updated_at' => $this->updated_at(),
|
'updated_at' => $this->updated_at(),
|
||||||
|
|||||||
46
database/migrations/2017_06_13_181049_CreateMetaTable.php
Normal file
46
database/migrations/2017_06_13_181049_CreateMetaTable.php
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Cachet.
|
||||||
|
*
|
||||||
|
* (c) Alt Three Services Limited
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateMetaTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('meta', function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->string('key')->index();
|
||||||
|
$table->string('value');
|
||||||
|
$table->integer('meta_id')->unsigned();
|
||||||
|
$table->string('meta_type');
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->index(['meta_id', 'meta_type']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('meta');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -154,4 +154,24 @@ class IncidentTest extends AbstractApiTestCase
|
|||||||
$this->delete('/api/v1/incidents/1');
|
$this->delete('/api/v1/incidents/1');
|
||||||
$this->assertResponseStatus(204);
|
$this->assertResponseStatus(204);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCreateIncidentWithMeta()
|
||||||
|
{
|
||||||
|
$this->beUser();
|
||||||
|
|
||||||
|
$this->post('/api/v1/incidents', [
|
||||||
|
'name' => 'Foo',
|
||||||
|
'message' => 'Lorem ipsum dolor sit amet',
|
||||||
|
'status' => 1,
|
||||||
|
'meta' => [
|
||||||
|
'id' => 123456789,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$this->seeJson([
|
||||||
|
'meta' => [
|
||||||
|
'id' => 123456789,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$this->assertResponseOk();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ class CreateIncidentCommandTest extends AbstractTestCase
|
|||||||
'occurred_at' => null,
|
'occurred_at' => null,
|
||||||
'template' => null,
|
'template' => null,
|
||||||
'template_vars' => [],
|
'template_vars' => [],
|
||||||
|
'meta' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
$object = new CreateIncidentCommand(
|
$object = new CreateIncidentCommand(
|
||||||
@@ -53,7 +54,8 @@ class CreateIncidentCommandTest extends AbstractTestCase
|
|||||||
$params['stickied'],
|
$params['stickied'],
|
||||||
$params['occurred_at'],
|
$params['occurred_at'],
|
||||||
$params['template'],
|
$params['template'],
|
||||||
$params['template_vars']
|
$params['template_vars'],
|
||||||
|
$params['meta']
|
||||||
);
|
);
|
||||||
|
|
||||||
return compact('params', 'object');
|
return compact('params', 'object');
|
||||||
|
|||||||
31
tests/Models/MetaTest.php
Normal file
31
tests/Models/MetaTest.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Cachet.
|
||||||
|
*
|
||||||
|
* (c) Alt Three Services Limited
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace CachetHQ\Tests\Cachet\Models;
|
||||||
|
|
||||||
|
use AltThree\TestBench\ValidationTrait;
|
||||||
|
use CachetHQ\Cachet\Models\Meta;
|
||||||
|
use CachetHQ\Tests\Cachet\AbstractTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the meta model test class.
|
||||||
|
*
|
||||||
|
* @author James Brooks <james@alt-three.com>
|
||||||
|
*/
|
||||||
|
class MetaTest extends AbstractTestCase
|
||||||
|
{
|
||||||
|
use ValidationTrait;
|
||||||
|
|
||||||
|
public function testValidation()
|
||||||
|
{
|
||||||
|
$this->checkRules(new Meta());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user