Skip to content

Commit

Permalink
- Added stats generate command
Browse files Browse the repository at this point in the history
  • Loading branch information
dash8x committed Jul 31, 2024
1 parent c9f4793 commit 056feb1
Show file tree
Hide file tree
Showing 7 changed files with 312 additions and 1 deletion.
106 changes: 106 additions & 0 deletions src/Commands/GenerateTimeSeriesStatCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

namespace Javaabu\Stats\Commands;

use Illuminate\Console\Command;
use Javaabu\GeneratorHelpers\Concerns\GeneratesFiles;
use Javaabu\Stats\Generators\AbstractStatGenerator;
use Javaabu\Stats\Generators\CountStatGenerator;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;

class GenerateTimeSeriesStatCommand extends Command
{
protected $name = 'stats:time-series';

protected $description = 'Generate time series stat';

use GeneratesFiles;

/** @return array */
protected function getArguments()
{
return [
['name', InputArgument::REQUIRED, 'The name for the stat class.'],
['model', InputArgument::REQUIRED, 'The model class for which you want to generate the stats for. Can be the model class or morph name.']
];
}

/** @return array */
protected function getOptions()
{
return [
['type', 't', InputOption::VALUE_REQUIRED, 'Which type of stat to generate. (Accepts count and sum).', 'count'],
['force', 'f', InputOption::VALUE_NONE, 'If stat gets created even if it already exists'],
['path', 'p', InputOption::VALUE_REQUIRED, 'Specify the path to create the files'],
];
}

public function handle(): int
{
// Arguments
$name = (string) $this->argument('name');
$model_class = (string) $this->argument('model');
$force = (bool) $this->option('force');
$path = (string) $this->option('path');
$type = (string) $this->option('type');

// create generator
$generator = $this->getGenerator($type, $name, $model_class);

// get the file path
$path = $this->getPath(app_path('Stats/TimeSeries'), $path);

$file_name = $generator->getName() . '.php';
$file_path = $this->getFullFilePath($path, $file_name);

$output = $generator->render();

if ($this->putContent($file_path, $output, $force)) {
$this->info("$file_name created!");
}

$this->registerStat($generator);

return Command::SUCCESS;
}

protected function getGenerator(string $type, string $name, string $model_class): AbstractStatGenerator
{
$class = $this->getGeneratorClass($type);

return new $class($name, $model_class);
}


/**
* @return class-string<AbstractStatGenerator>
*/
protected function getGeneratorClass(string $type): string
{
return match ($type) {
'count' => CountStatGenerator::class
};
}

protected function registerStat(AbstractStatGenerator $generator): void
{
$file_path = app_path('Providers/AppServiceProvider.php');

$metric = $generator->getMetric();
$class_name = $generator->getFullClassName();
$name = $generator->getName();

$replacements = [
[
'search' => "TimeSeriesStats::register([\n",
'keep_search' => true,
'content' => $this->getRenderer()->addIndentation("'$metric' => $class_name::class,\n", 3),
],
];

if ($this->appendContent($file_path, $replacements)) {
$this->info("$name stat registered!");
}
}
}
14 changes: 13 additions & 1 deletion src/Generators/AbstractStatGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ abstract class AbstractStatGenerator
protected string $name;
protected string $model_class;
protected string $table;
protected string $metric;
protected StubRenderer $renderer;

/**
* Constructor
*/
public function __construct(string $name, string $model_class)
{
$this->name = $name;
$this->name = StringCaser::studly($name);
$this->metric = StringCaser::snake($this->name);
$this->model_class = $this->resolveFullModelClass($model_class);
$this->table = $this->resolveTableName($this->model_class);
$this->renderer = app()->make(StubRenderer::class);
Expand Down Expand Up @@ -113,4 +115,14 @@ public function getName(): string
{
return $this->name;
}

public function getMetric(): string
{
return $this->metric;
}

public function getFullClassName(): string
{
return '\\App\\Stats\\TimeSeries\\' . $this->getName();
}
}
5 changes: 5 additions & 0 deletions src/StatsServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
use Javaabu\GeneratorHelpers\StubRenderer;
use Javaabu\Stats\Commands\GenerateTimeSeriesStatCommand;
use Javaabu\Stats\Formatters\TimeSeries\ChartjsStatsFormatter;
use Javaabu\Stats\Formatters\TimeSeries\CombinedStatsFormatter;
use Javaabu\Stats\Formatters\TimeSeries\DefaultStatsFormatter;
Expand Down Expand Up @@ -34,6 +35,10 @@ public function boot()
$this->publishes([
__DIR__ . '/../stubs' => base_path('stubs/vendor/stats'),
], 'stats-stubs');

$this->commands([
GenerateTimeSeriesStatCommand::class,
]);
}

$this->loadViewsFrom(__DIR__ . '/../resources/views', 'stats');
Expand Down
75 changes: 75 additions & 0 deletions tests/Feature/Commands/GenerateTimeSeriesStatCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace Javaabu\Stats\Tests\Feature\Commands;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Javaabu\Stats\Tests\TestCase;
use Javaabu\Stats\Tests\TestSupport\Models\Payment;

class GenerateTimeSeriesStatCommandTest extends TestCase
{
use RefreshDatabase;

public function setUp(): void
{
parent::setUp();

// delete all stats
$this->deleteDirectory($this->app->path('Stats'));

// setup skeleton service provider
$this->copyFile(
$this->getTestStubPath('Providers/SkeletonAppServiceProvider.php'),
$this->app->path('Providers/AppServiceProvider.php')
);
}

protected function tearDown(): void
{
$this->deleteDirectory($this->app->path('Stats'));

// setup standard service provider
$this->copyFile(
$this->getTestStubPath('Providers/AppServiceProvider.php'),
$this->app->path('Providers/AppServiceProvider.php')
);

parent::tearDown();
}

/** @test */
public function it_can_generate_a_new_count_stat_file(): void
{
$expected_path = $this->app->path('Stats/TimeSeries/PaymentsCount.php');
$expected_content = $this->getTestStubContents('Stats/TimeSeries/PaymentsCount.php');

$this->artisan('stats:time-series', ['name' => 'PaymentsCount', 'model' => Payment::class])
->assertSuccessful();

$this->assertFileExists($expected_path);

$actual_content = $this->getGeneratedFileContents($expected_path);
$this->assertEquals($expected_content, $actual_content);
}

/** @test */
public function it_registers_stats_maps(): void
{
$expected_path = $this->app->path('Stats/TimeSeries/PaymentsCount.php');
$expected_content = $this->getTestStubContents('Stats/TimeSeries/PaymentsCount.php');

$this->artisan('stats:time-series', ['name' => 'PaymentsCount', 'model' => Payment::class])
->assertSuccessful();

$this->assertFileExists($expected_path);

$actual_content = $this->getGeneratedFileContents($expected_path);
$this->assertEquals($expected_content, $actual_content);

$expected_path = $this->app->path('Providers/AppServiceProvider.php');
$expected_content = $this->getTestStubContents('Providers/StatsAppServiceProvider.php');
$actual_content = $this->getGeneratedFileContents($expected_path);

$this->assertEquals($expected_content, $actual_content);
}
}
24 changes: 24 additions & 0 deletions tests/TestSupport/stubs/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}

/**
* Bootstrap any application services.
*/
public function boot(): void
{
//
}
}
44 changes: 44 additions & 0 deletions tests/TestSupport/stubs/Providers/SkeletonAppServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace App\Providers;

use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\ServiceProvider;
use Javaabu\Activitylog\CauserTypes;
use Javaabu\Activitylog\SubjectTypes;
use Javaabu\Stats\TimeSeriesStats;

class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}

/**
* Bootstrap any application services.
*/
public function boot(): void
{
TimeSeriesStats::register([
]);

Relation::enforceMorphMap([
'user' => \App\Models\User::class,
'oauth_client' => \Laravel\Passport\Client::class,
'role' => \Javaabu\Permissions\Models\Role::class,
]);

SubjectTypes::register([
\App\Models\User::class,
\Javaabu\Permissions\Models\Role::class,
]);

CauserTypes::register([
\App\Models\User::class,
]);
}
}
45 changes: 45 additions & 0 deletions tests/TestSupport/stubs/Providers/StatsAppServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace App\Providers;

use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\ServiceProvider;
use Javaabu\Activitylog\CauserTypes;
use Javaabu\Activitylog\SubjectTypes;
use Javaabu\Stats\TimeSeriesStats;

class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}

/**
* Bootstrap any application services.
*/
public function boot(): void
{
TimeSeriesStats::register([
'payments_count' => \App\Stats\TimeSeries\PaymentsCount::class,
]);

Relation::enforceMorphMap([
'user' => \App\Models\User::class,
'oauth_client' => \Laravel\Passport\Client::class,
'role' => \Javaabu\Permissions\Models\Role::class,
]);

SubjectTypes::register([
\App\Models\User::class,
\Javaabu\Permissions\Models\Role::class,
]);

CauserTypes::register([
\App\Models\User::class,
]);
}
}

0 comments on commit 056feb1

Please sign in to comment.