This page contains information for developers who want to contribute to the Manta Laravel Flux CMS package.
git clone https://github.com/manta/laravel-manta-cms.git
cd laravel-manta-cms
composer install
npm install
# In your Laravel project
composer config repositories.manta-cms path "../path/to/laravel-manta-cms"
composer require manta/laravel-manta-cms:@dev
Run tests with PHPUnit:
# All tests
./vendor/bin/phpunit
# Specific test
./vendor/bin/phpunit tests/Unit/MantaRouteTest.php
# With coverage
./vendor/bin/phpunit --coverage-html coverage
The package uses Laravel Pint for code formatting:
# Check code style
./vendor/bin/pint --test
# Fix code style
./vendor/bin/pint
Use PHPStan for static analysis:
./vendor/bin/phpstan analyse
src/
├── Console/
│ └── Commands/ # Artisan commands
├── Http/
│ ├── Controllers/ # Controllers
│ ├── Middleware/ # Middleware
│ └── Requests/ # Form requests
├── Models/ # Eloquent models
├── Providers/ # Service providers
└── Views/ # Blade templates
database/
├── migrations/ # Database migrations
└── seeders/ # Database seeders
config/
└── flux-cms.php # Package configuration
resources/
├── views/ # Blade views
├── css/ # Stylesheets
└── js/ # JavaScript
tests/
├── Unit/ # Unit tests
├── Feature/ # Feature tests
└── TestCase.php # Base test case
# Create model
php artisan make:model Models/MantaExample
# Create migration
php artisan make:migration create_manta_examples_table
Follow existing conventions:
Manta
prefix for model namesHasFactory
traitcreated_by
, updated_by
fieldsphp artisan make:command ExampleCommand
Conventions:
manta:
prefix for command signaturesrc/Console/Commands/
FluxCMSServiceProvider
docs/commands.md
php artisan make:livewire ExampleComponent
Conventions:
Conventions:
2023_01_01_000000_
created_by
, updated_by
fieldsTest individual methods and classes:
<?php
namespace Tests\Unit;
use Tests\TestCase;
use Manta\FluxCMS\Models\MantaRoute;
class MantaRouteTest extends TestCase
{
public function test_can_create_route()
{
$route = MantaRoute::create([
'uri' => 'test/route',
'name' => 'test.route',
'prefix' => 'test',
'active' => true
]);
$this->assertInstanceOf(MantaRoute::class, $route);
$this->assertEquals('test/route', $route->uri);
}
public function test_active_scope_filters_correctly()
{
MantaRoute::factory()->create(['active' => true]);
MantaRoute::factory()->create(['active' => false]);
$activeRoutes = MantaRoute::active()->get();
$this->assertCount(1, $activeRoutes);
$this->assertTrue($activeRoutes->first()->active);
}
}
Test complete features:
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Manta\FluxCMS\Models\MantaRoute;
class SyncRoutesCommandTest extends TestCase
{
public function test_sync_routes_command_works()
{
$this->artisan('manta:sync-routes')
->expectsOutput('Routes synchronized!')
->assertExitCode(0);
$this->assertDatabaseHas('manta_routes', [
'name' => 'cms.dashboard'
]);
}
public function test_sync_routes_with_prefix_filter()
{
$this->artisan('manta:sync-routes --prefix=cms')
->assertExitCode(0);
$routes = MantaRoute::where('prefix', 'cms')->get();
$this->assertGreaterThan(0, $routes->count());
}
}
Test Livewire components:
<?php
namespace Tests\Feature;
use Livewire\Livewire;
use Tests\TestCase;
use App\Livewire\UserTable;
class UserTableTest extends TestCase
{
public function test_can_render_component()
{
Livewire::test(UserTable::class)
->assertStatus(200);
}
public function test_can_search_users()
{
$user = User::factory()->create(['name' => 'John Doe']);
Livewire::test(UserTable::class)
->set('search', 'John')
->assertSee('John Doe');
}
}
manta_
prefix, snake_case, plural{model}_id
created_at
, updated_at
created_by
, updated_by
Add these columns to every table:
$table->id();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamps();
// For soft deletes (if needed)
$table->unsignedBigInteger('deleted_by')->nullable();
$table->softDeletes();
<?php
namespace Manta\FluxCMS\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
/**
* MantaRoute model for managing Laravel routes
*
* @property int $id
* @property string $uri
* @property string $name
* @property string $prefix
* @property bool $active
*/
class MantaRoute extends Model
{
protected $fillable = [
'uri',
'name',
'prefix',
'active'
];
protected $casts = [
'active' => 'boolean'
];
/**
* Scope for active routes
*/
public function scopeActive(Builder $query): Builder
{
return $query->where('active', true);
}
}
<div class="space-y-6">
<flux:heading size="lg">
</flux:heading>
<flux:table>
<flux:columns>
<flux:column>Name</flux:column>
<flux:column>Status</flux:column>
</flux:columns>
<flux:rows>
@foreach($items as $item)
<flux:row wire:key="">
<flux:cell></flux:cell>
<flux:cell>
<flux:badge :variant="$item->active ? 'success' : 'danger'">
</flux:badge>
</flux:cell>
</flux:row>
@endforeach
</flux:rows>
</flux:table>
</div>
The package follows Semantic Versioning:
CHANGELOG.md
# Tests
./vendor/bin/phpunit
./vendor/bin/pint --test
./vendor/bin/phpstan analyse
# Tag release
git tag v1.2.3
git push origin v1.2.3