PHP code example of inlayphp / resources

1. Go to this page and download the library: Download inlayphp/resources library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

inlayphp / resources example snippets


use App\Models\User;
use App\Validation\UserRules;
use Illuminate\Database\Eloquent\Model;
use Inlay\Forms\Fields\TextInput;
use Inlay\Forms\Form;
use Inlay\Resources\Resource;
use Inlay\Resources\ResourceOperation;
use Inlay\Tables\Columns\TextColumn;
use Inlay\Tables\Table;

final class UserResource extends Resource
{
    protected static string $model = User::class;

    public static function table(Table $table): Table
    {
        return $table->columns([
            TextColumn::make('name')->searchable()->sortable(),
        ]);
    }

    public static function form(Form $form): Form
    {
        return $form->schema([
            TextInput::make('name')->

final class ListUsers extends ListRecords
{
    protected static string $resource = UserResource::class;
    protected static string $component = 'users/index';
}

final class OrderResource extends Resource
{
    protected static ?string $navigationIcon = 'shopping-bag';
    protected static ?string $navigationGroup = 'Shop';
    protected static int $navigationSort = 30;
    protected static string|int|null $navigationBadge = 12;
}

final class UserResource extends Resource
{
    public static function globallySearchableAttributes(): array
    {
        return ['name', 'email'];
    }
}

GlobalSearch::across([UserResource::class, OrderResource::class])
    ->search($request->string('q'), $request->user(), prefix: 'admin');

final class UserResource extends Resource
{
    public static function recordTitleAttribute(): ?string
    {
        return 'name';
    }
}

final class UserResource extends Resource
{
    public static function recordSubNavigation(): array
    {
        return ['view', 'edit', 'notes'];
    }
}

final class ViewUser extends ViewRecord
{
    public static function subNavigationLabel(): string
    {
        return 'Overview';
    }
}

final class ListOrders extends ListRecords
{
    protected function tabs(): array
    {
        return [
            PageTab::make('all')->label('All orders')->default(),
            PageTab::make('unpaid')
                ->badge(fn (): int => Order::query()->where('status', 'unpaid')->count())
                ->modifyQueryUsing(fn (Builder $query): Builder => $query->where('status', 'unpaid')),
        ];
    }
}

final class ManageOrderItems extends ManageRelatedRecords
{
    protected static string $resource = OrderResource::class;

    protected static string $component = 'orders/items';

    protected static string $relationManager = ItemsRelationManager::class;
}

// In the resource:
'items' => ManageOrderItems::route('/{record}/items'),

final class ListOrders extends ListRecords
{
    protected function headerActions(): array
    {
        return [
            Action::make('export')
                ->authorizeUsing(fn (Request $request): bool => $request->user() !== null)
                ->action(fn () => ExportOrders::dispatch()),
            Action::make('docs')->url('https://example.com/docs'),
        ];
    }
}

final class OrderResource extends Resource
{
    public static function widgets(): array
    {
        return [RevenueOverview::class];
    }
}

final class ListOrders extends ListRecords
{
    protected function footerWidgets(): array
    {
        return [OrdersPerDayChart::make('orders-per-day')];
    }
}

use App\Inlay\Resources\UserResource;
use Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests;
use Inlay\Resources\Facades\InlayResources;

InlayResources::routes([UserResource::class], [
    'middleware' => ['auth'],
    'mutationMiddleware' => [HandlePrecognitiveRequests::class],
    // 'prefix' => 'admin',
    // 'name' => 'admin.inlay.',
]);

public function panel(Panel $panel): Panel
{
    return $panel
        ->path('/admin')
        ->middleware(['web'])
        ->authMiddleware(['auth'])
        ->resources([UserResource::class]);
}

final class UserRules extends Validation
{
    public function rules(ValidationContext $context): array
    {
        return [
            'name' => ['       ],
        ];
    }
}

Select::make('author_id')
    ->getSearchResultsUsing(fn (string $search): array => User::query()
        ->where('name', 'like', "%{$search}%")
        ->limit(50)
        ->pluck('name', 'id')
        ->all())
    ->getOptionLabelUsing(
        fn (int|string $value): ?string => User::find($value)?->name,
    )
    ->preload()
    ->searchDebounce(500);

Select::make('author_id')
    ->relationship('author', 'name')
    ->searchable()
    ->preload();

Select::make('roles')
    ->relationship(
        'roles',
        'name',
        fn ($query) => $query->where('assignable', true),
    )
    ->searchable()
    ->pivotData(fn (int|string $roleId, User $user): array => [
        'assigned_by' => auth()->id(),
    ]);

use App\Validation\UserPostRules;
use Illuminate\Database\Eloquent\Model;
use Inlay\Forms\Fields\TextInput;
use Inlay\Forms\Form;
use Inlay\Resources\RelationManager;
use Inlay\Resources\RelationOperation;
use Inlay\Tables\Columns\TextColumn;
use Inlay\Tables\Table;

final class PostsRelationManager extends RelationManager
{
    protected static string $relationship = 'posts';

    protected static ?string $recordTitleAttribute = 'title';

    public function table(Table $table): Table
    {
        return $table->columns([
            TextColumn::make('title')->searchable()->sortable(),
        ]);
    }

    public function form(Form $form): Form
    {
        return $form->schema([
            TextInput::make('title')->n::Restore => 'restore',
                RelationOperation::RestoreAny => 'restoreAny',
                RelationOperation::ForceDelete => 'forceDelete',
                RelationOperation::ForceDeleteAny => 'forceDeleteAny',
                RelationOperation::Detach => 'detach',
                RelationOperation::Dissociate => 'dissociate',
            },
            $record ?? Post::class,
        ) ?? false;
    }
}

public static function getRelations(): array
{
    return [PostsRelationManager::class];
}

use Inlay\Resources\RelationGroup;

public static function getRelations(): array
{
    return [
        RelationGroup::make('Customer activity', [
            OrdersRelationManager::class,
            NotesRelationManager::class,
            TicketsRelationManager::class,
        ])
            ->description('Orders, internal notes, and support history.')
            ->icon('heroicon-o-link')
            ->defaultRelation(OrdersRelationManager::class),

        AddressesRelationManager::class,
    ];
}

use Inlay\Resources\ParentResourceRegistration;

final class UserNoteResource extends Resource
{
    protected static string $model = UserNote::class;

    protected static ?string $slug = 'notes';

    public static function getParentResourceRegistration(): ParentResourceRegistration
    {
        return UserResource::asParent()
            ->relationship('notes')
            ->inverseRelationship('user');
    }
}

UserNoteResource::url('index', parent: $user);          // /users/1/notes
UserNoteResource::url('edit', $note, $user);            // /users/1/notes/7/edit
UserNoteResource::baseUrl('admin', $user);              // /admin/users/1/notes

final class Post extends Model
{
    use \Illuminate\Database\Eloquent\SoftDeletes;
}

final class PostsRelationManager extends RelationManager
{
    protected static string $relationship = 'posts';

    protected static bool $softDeletes = true;
}

use Illuminate\Database\Eloquent\Builder;

protected function modifyAttachQuery(Builder $query): Builder
{
    return $query
        ->where('team_id', auth()->user()->team_id)
        ->where('archived', false);
}

use App\Validation\RoleAssignmentRules;
use Inlay\Forms\Fields\TextInput;

public function attachForm(Form $form): Form
{
    return $form->schema([
        $this->getAttachRecordSelect(),
        TextInput::make('assignment_note')
            ->

return $this->belongsToMany(Role::class)
    ->withPivot('assignment_note');

public function form(Form $form): Form
{
    return $form->schema([
        TextInput::make('name')->on(): string
{
    return RoleAssignmentRules::class;
}

/**
 * @param  Builder<Post>  $query
 * @return Builder<Post>
 */
protected function modifyAssociateQuery(Builder $query): Builder
{
    return $query
        ->where('team_id', auth()->user()->team_id)
        ->whereIn('status', ['draft', 'published']);
}

protected static function mutateDataBeforeCreate(array $data): array
{
    return [...$data, 'password' => Str::random(32)];
}

protected static function beforeUpdate(Model $record, array $data): void {}
protected static function afterUpdate(Model $record, array $data): void {}

public static function successMessage(ResourceOperation $operation, Model $record): string
{
    return match ($operation) {
        ResourceOperation::Create => 'User invited.',
        default => parent::successMessage($operation, $record),
    };
}

use Illuminate\Database\Eloquent\SoftDeletes;

final class User extends Model
{
    use SoftDeletes;
}

final class UserResource extends Resource
{
    protected static string $model = User::class;

    protected static bool $softDeletes = true;
}

public function restore(User $user, Post $post): bool {}
public function restoreAny(User $user): bool {}
public function forceDelete(User $user, Post $post): bool {}
public function forceDeleteAny(User $user): bool {}
public function deleteAny(User $user): bool {}

final class ProjectResource extends Resource
{
    protected static string $model = Project::class;

    protected static ?string $tenantRelationship = 'team';
}

Tenancy::resolve()->set($request->user()->currentTeam);

InlayResources::routes([ProjectResource::class], [
    'prefix' => 'admin',
    'tenant' => ['model' => Team::class, 'parameter' => 'team', 'routeKey' => 'slug'],
]);

final class Team extends Model implements TenantAccess
{
    public function canAccessTenant(mixed $user): bool
    {
        return $user !== null && $this->members()->whereKey($user->getKey())->exists();
    }
}

it('searches and filters users', function () {
    $users = User::factory()->count(5)->create();

    inlay(UserResource::class, user: $this->admin)
        ->assertRelationGroupExists('customer-activity')
        ->assertRelationManagerExists('orders', 'customer-activity')
        ->assertTableColumnExists('email')
        ->assertTableFilterExists('status')
        ->assertCanSeeTableRecords($users)
        ->searchTable($users->first()->email)
        ->assertCanSeeTableRecords($users->take(1))
        ->assertCanNotSeeTableRecords($users->skip(1))
        ->resetTable()
        ->filterTable('status', 'active')
        ->sortTable('name', 'desc');
});

inlay(ProjectResource::class, user: $this->member)
    ->assertTenantScoped()
    ->forTenant($acme)
    ->assertCanSeeTableRecords($acmeProjects)
    ->assertCanNotSeeTableRecords($globexProjects)
    // Another tenant's record is unreachable, not merely hidden.
    ->assertRecordOutsideTenant($globexProject)
    ->forTenant($globex)
    ->assertCanSeeTableRecords($globexProjects);

inlay(UserResource::class, user: $this->admin)
    ->assertFormFieldExists('email')
    ->fillForm([
        'name' => 'Ada Lovelace',
        'email' => null,
    ])
    ->call('create')
    ->assertHasFormErrors([
        'email' => ')->toBeInstanceOf(User::class);

inlay(UserResource::class, user: $this->admin)
    ->forEdit($user)
    ->fillForm(['name' => 'Updated name'])
    ->call('save')
    ->assertHasNoFormErrors()
    ->editTableColumn($user, 'active', false)
    ->assertTableColumnStateSet('active', false, $user);

inlay(UserResource::class, user: $this->admin)
    ->assertTableActionExists('activate')
    ->mountTableAction('activate', $user)
    ->fillTableActionForm(['reason' => 'Identity reviewed'])
    ->callMountedTableAction()
    ->assertHasNoTableActionErrors()
    ->assertTableActionSucceeded();

inlay(UserResource::class, user: $this->admin)
    ->assertTableHeaderActionExists('export')
    ->callTableHeaderAction('export')
    ->assertTableActionSucceeded(
        fn (mixed $result): bool => $result['queued'] === true,
    );

inlay(UserResource::class, user: $this->admin)
    ->assertTableBulkActionExists('suspend')
    ->selectTableRecords([$firstUser, $secondUser])
    ->callTableBulkAction('suspend', ['reason' => 'Review'])
    ->assertHasNoTableActionErrors()
    ->assertTableActionSucceeded();
bash
php artisan make:inlay-resource User
bash
php artisan make:inlay-resource User --generate
bash
php artisan make:inlay-relation-manager UserResource posts title