Merge branch '2.4' into feature/merge-install-commands

This commit is contained in:
Nico Stapelbroek
2018-07-03 14:39:38 +02:00
committed by GitHub
19 changed files with 147 additions and 86 deletions

View File

@@ -45,15 +45,6 @@ Here are some useful quick links:
### Demo
To test out the demo, you may login to the [Dashboard](https://demo.cachethq.io/dashboard) with the following:
- **Username:** `test` or `test@test.com`
- **Password:** `test123`
> The demo resets every 30 minutes.
### v2.4 Demo
To test out the demo, you may login to the [Dashboard](https://dev.cachethq.io/dashboard) with the following:
- **Username:** `test` or `test@test.com`

View File

@@ -12,8 +12,6 @@
namespace CachetHQ\Cachet\Console\Commands;
use CachetHQ\Cachet\Models\MetricPoint;
use DateInterval;
use DateTime;
use Illuminate\Console\Command;
use Illuminate\Console\ConfirmableTrait;
use Symfony\Component\Console\Input\InputOption;
@@ -66,16 +64,26 @@ class DemoMetricPointSeederCommand extends Command
{
MetricPoint::truncate();
// Generate 11 hours of metric points
for ($i = 0; $i < 11; $i++) {
$metricTime = (new DateTime())->sub(new DateInterval('PT'.$i.'H'));
$points = [];
MetricPoint::create([
'metric_id' => 1,
'value' => random_int(1, 10),
'created_at' => $metricTime,
'updated_at' => $metricTime,
]);
// Generate 24 hours of metric points
for ($i = 0; $i <= 23; $i++) {
for ($j = 0; $j <= 59; $j++) {
$this->info("{$i}:{$j}");
$pointTime = date("Y-m-d {$i}:{$j}:00");
$points[] = [
'metric_id' => 1,
'value' => random_int(1, 10),
'created_at' => $pointTime,
'updated_at' => $pointTime,
];
}
}
foreach (array_chunk($points, 100) as $chunk) {
MetricPoint::insert($chunk);
}
}

View File

@@ -24,7 +24,7 @@ use Illuminate\Support\Facades\View;
/**
* This is the component group controller class.
*
* @author James Brooks <james@bluebaytravel.co.uk>
* @author James Brooks <james@alt-three.com>
*/
class ComponentGroupController extends Controller
{

View File

@@ -81,10 +81,6 @@ class Beacon implements BeaconContract
return;
}
if (!($contactEmail = User::admins()->active()->first()->email)) {
$contactEmail = null;
}
$setting = app(Setting::class);
if (!$installId = $setting->get('install_id', null)) {
@@ -94,12 +90,11 @@ class Beacon implements BeaconContract
}
$payload = [
'install_id' => $installId,
'version' => CACHET_VERSION,
'docker' => $this->config->get('cachet.is_docker'),
'database' => $this->config->get('database.default'),
'contact_email' => $contactEmail,
'data' => [
'install_id' => $installId,
'version' => CACHET_VERSION,
'docker' => $this->config->get('cachet.is_docker'),
'database' => $this->config->get('database.default'),
'data' => [
'components' => Component::all()->count(),
'incidents' => Incident::all()->count(),
'metrics' => Metric::all()->count(),

View File

@@ -182,7 +182,7 @@ class Metric extends Model implements HasPresenter
*/
public function points()
{
return $this->hasMany(MetricPoint::class, 'metric_id', 'id');
return $this->hasMany(MetricPoint::class, 'metric_id', 'id')->latest();
}
/**

View File

@@ -29,6 +29,15 @@ class MetricPoint extends Model implements HasPresenter
{
use ValidatingTrait;
/**
* The accessors to append to the model's array form.
*
* @var string[]
*/
protected $appends = [
'calculated_value',
];
/**
* The model's attributes.
*
@@ -82,19 +91,13 @@ class MetricPoint extends Model implements HasPresenter
}
/**
* Override the value attribute.
* Show the actual calculated value; as per (value * counter).
*
* @param mixed $value
*
* @return float
* @return int
*/
public function getActiveValueAttribute($value)
public function getCalculatedValueAttribute()
{
if ($this->metric->calc_type === Metric::CALC_SUM) {
return round((float) $value * $this->counter, $this->metric->places);
}
return round((float) $value, $this->metric->places);
return $this->value * $this->counter;
}
/**
@@ -117,7 +120,11 @@ class MetricPoint extends Model implements HasPresenter
$timestamp = $createdAt->format('U');
$timestamp = 30 * round($timestamp / 30);
return Carbon::createFromFormat('U', $timestamp)->toDateTimeString();
$date = Carbon::createFromFormat('U', $timestamp)->toDateTimeString();
$this->attributes['created_at'] = $date;
return $date;
}
/**

View File

@@ -19,16 +19,6 @@ class MetricPointPresenter extends BasePresenter implements Arrayable
{
use TimestampsTrait;
/**
* Show the actual calculated value; as per (value * counter).
*
* @return int
*/
public function calculated_value()
{
return $this->wrappedObject->value * $this->wrappedObject->counter;
}
/**
* Convert the presenter instance to an array.
*
@@ -37,9 +27,8 @@ class MetricPointPresenter extends BasePresenter implements Arrayable
public function toArray()
{
return array_merge($this->wrappedObject->toArray(), [
'created_at' => $this->created_at(),
'updated_at' => $this->updated_at(),
'calculated_value' => $this->calculated_value(),
'created_at' => $this->created_at(),
'updated_at' => $this->updated_at(),
]);
}
}

View File

@@ -18,7 +18,7 @@ use McCool\LaravelAutoPresenter\BasePresenter;
/**
* This is the user presenter class.
*
* @author James Brooks <james@bluebaytravel.co.uk>
* @author James Brooks <james@alt-three.com>
*/
class UserPresenter extends BasePresenter implements Arrayable
{

View File

@@ -98,7 +98,7 @@ class MetricRepository
$pointKey = $dateTime->format('Y-m-d H:00');
$points = $this->repository->getPointsSinceHour($metric, $hours)->pluck('value', 'key');
for ($i = 0; $i <= $hours; $i++) {
for ($i = 0; $i < $hours; $i++) {
if (!$points->has($pointKey)) {
$points->put($pointKey, $metric->default_value);
}

View File

@@ -13,7 +13,6 @@ namespace CachetHQ\Cachet\Repositories\Metric;
use CachetHQ\Cachet\Models\Metric;
use Illuminate\Support\Facades\DB;
use Jenssegers\Date\Date;
/**
* This is the pgsql repository class.

View File

@@ -13,7 +13,6 @@ namespace CachetHQ\Cachet\Repositories\Metric;
use CachetHQ\Cachet\Models\Metric;
use Illuminate\Support\Facades\DB;
use Jenssegers\Date\Date;
/**
* This is the sqlite repository class.

44
composer.lock generated
View File

@@ -409,16 +409,16 @@
},
{
"name": "aws/aws-sdk-php",
"version": "3.62.5",
"version": "3.62.6",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
"reference": "75113b0ba22fffd968c45f06ba20fa94509dc973"
"reference": "0be301c36a5c337b40e69ce3b4698cca5427e4b9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/75113b0ba22fffd968c45f06ba20fa94509dc973",
"reference": "75113b0ba22fffd968c45f06ba20fa94509dc973",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/0be301c36a5c337b40e69ce3b4698cca5427e4b9",
"reference": "0be301c36a5c337b40e69ce3b4698cca5427e4b9",
"shasum": ""
},
"require": {
@@ -485,7 +485,7 @@
"s3",
"sdk"
],
"time": "2018-06-28T21:12:53+00:00"
"time": "2018-06-29T22:12:11+00:00"
},
{
"name": "bacon/bacon-qr-code",
@@ -3919,16 +3919,16 @@
},
{
"name": "swiftmailer/swiftmailer",
"version": "v6.0.2",
"version": "v6.1.0",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "412333372fb6c8ffb65496a2bbd7321af75733fc"
"reference": "0ff595e1d9d7d1c929b2a5f7b774bbcfbbd81587"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/412333372fb6c8ffb65496a2bbd7321af75733fc",
"reference": "412333372fb6c8ffb65496a2bbd7321af75733fc",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/0ff595e1d9d7d1c929b2a5f7b774bbcfbbd81587",
"reference": "0ff595e1d9d7d1c929b2a5f7b774bbcfbbd81587",
"shasum": ""
},
"require": {
@@ -3939,10 +3939,14 @@
"mockery/mockery": "~0.9.1",
"symfony/phpunit-bridge": "~3.3@dev"
},
"suggest": {
"ext-intl": "Needed to support internationalized email addresses",
"true/punycode": "Needed to support internationalized email addresses, if ext-intl is not installed"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "6.0-dev"
"dev-master": "6.1-dev"
}
},
"autoload": {
@@ -3964,13 +3968,13 @@
}
],
"description": "Swiftmailer, free feature-rich PHP mailer",
"homepage": "http://swiftmailer.symfony.com",
"homepage": "https://swiftmailer.symfony.com",
"keywords": [
"email",
"mail",
"mailer"
],
"time": "2017-09-30T22:39:41+00:00"
"time": "2018-07-02T20:24:38+00:00"
},
{
"name": "symfony/console",
@@ -4955,28 +4959,28 @@
},
{
"name": "vlucas/phpdotenv",
"version": "v2.4.0",
"version": "v2.5.0",
"source": {
"type": "git",
"url": "https://github.com/vlucas/phpdotenv.git",
"reference": "3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c"
"reference": "6ae3e2e6494bb5e58c2decadafc3de7f1453f70a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c",
"reference": "3cc116adbe4b11be5ec557bf1d24dc5e3a21d18c",
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/6ae3e2e6494bb5e58c2decadafc3de7f1453f70a",
"reference": "6ae3e2e6494bb5e58c2decadafc3de7f1453f70a",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"require-dev": {
"phpunit/phpunit": "^4.8 || ^5.0"
"phpunit/phpunit": "^4.8.35 || ^5.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
"dev-master": "2.5-dev"
}
},
"autoload": {
@@ -4986,7 +4990,7 @@
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause-Attribution"
"BSD-3-Clause"
],
"authors": [
{
@@ -5001,7 +5005,7 @@
"env",
"environment"
],
"time": "2016-09-01T10:05:43+00:00"
"time": "2018-07-01T10:25:50+00:00"
},
{
"name": "zendframework/zend-diactoros",

View File

@@ -85,9 +85,11 @@ $factory->define(Metric::class, function ($faker) {
$factory->define(MetricPoint::class, function ($faker) {
return [
'metric_id' => factory(Metric::class)->create()->id,
'value' => mt_rand(1, 100),
'counter' => 1,
'metric_id' => factory(Metric::class)->create()->id,
'value' => mt_rand(1, 100),
'counter' => 1,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
];
});

19
docs/beacon.md Normal file
View File

@@ -0,0 +1,19 @@
# About Beacon and the information we collect
To help us understand how Cachet is used, we collect anonymous usage data.
If you'd prefer not to provide us with this anonymous usage data, please set `CACHET_BEACON` to `false` in your `.env` file.
## Data collected by Beacon
- `install_id` - a unique, anonymous installation ID
- `version` - the version of Cachet being used
- `docker` - whether Cachet is being ran from a Docker container
- `database` - the database driver being used
- `data.components` - the amount of configured Components
- `data.incidents` - the amount of reported Incidents
- `data.metrics` - the amount of configured Metrics
- `data.users` - the amount of users
- `data.actions` - the amount of actions performed
- `data.tags` - the amount of Tags created
- `data.schedules` - the amount of reported Schedules

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -14,6 +14,7 @@
@import "dashboard/pages/dashboard";
// Styles for plugins
/*! purgecss start ignore */
@import "plugins/jquery.minicolors";
@import "plugins/github-markdown";
@import "plugins/sweetalert";
@@ -21,3 +22,4 @@
@import "plugins/animate";
@import "plugins/password-strength";
@import "plugins/sortable";
/*! purgecss end ignore */

View File

@@ -1,3 +1,4 @@
/*! purgecss start ignore */
@import "./node_modules/flatpickr/dist/flatpickr";
.flatpickr-calendar {
@@ -59,3 +60,4 @@
.flatpickr-time {
text-align: left;
}
/*! purgecss end ignore */

View File

@@ -39,6 +39,38 @@ class MetricPointTest extends AbstractApiTestCase
$response->assertStatus(200);
}
public function test_can_get_all_metric_points_in_order_by_latests()
{
$metric = factory(Metric::class)->create();
$metricPoint1 = factory(MetricPoint::class)->create([
'metric_id' => $metric->id,
'created_at' => Carbon::parse('2016-12-01 2:00pm'),
'updated_at' => Carbon::parse('2016-12-01 2:00pm'),
]);
$metricPoint2 = factory(MetricPoint::class)->create([
'metric_id' => $metric->id,
'created_at' => Carbon::parse('2016-12-01 1:00pm'),
'updated_at' => Carbon::parse('2016-12-01 1:00pm'),
]);
$metricPoint3 = factory(MetricPoint::class)->create([
'metric_id' => $metric->id,
'created_at' => Carbon::parse('2016-12-01 4:00pm'),
'updated_at' => Carbon::parse('2016-12-01 4:00pm'),
]);
$response = $this->json('GET', "/api/v1/metrics/{$metric->id}/points");
$response->assertJson([
'data' => [
['id' => $metricPoint3->id],
['id' => $metricPoint1->id],
['id' => $metricPoint2->id],
],
]);
$response->assertStatus(200);
}
public function test_cannot_create_metric_point_without_authorization()
{
$metric = factory(Metric::class)->create();