PHP code example of axyr / laravel-tractor

1. Go to this page and download the library: Download axyr/laravel-tractor 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/ */

    

axyr / laravel-tractor example snippets




namespace App\Modules\Posts\Models;

use Axyr\CrudGenerator\Filters\Traits\FiltersRecords;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;

/**
 * @property int $id
 *
 * @property Carbon $created_at
 * @property Carbon $updated_at
 */
class Post extends Model
{
    use FiltersRecords;

    protected $guarded = ['id'];
}



namespace Modules\Posts\Http\Controllers;

use Illuminate\Routing\Controller;
use Modules\Posts\Models\Post;
use Modules\Posts\Repositories\PostRepository;
use Modules\Posts\Http\Requests\PostRequest;
use Modules\Posts\Http\Resources\PostResource;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Http\Response;

class PostController extends Controller
{
    use AuthorizesRequests;

    public function __construct(protected PostRepository $repository)
    {
        $this->authorizeResource(Post::class);
    }

    public function index(Request $request): ResourceCollection
    {
        $posts = $this->repository->setRequest($request)->paginate();

        return PostResource::collection($posts)->preserveQuery();
    }

    public function store(PostRequest $request): PostResource
    {
        $post = Post::query()->create($request->validated());

        return new PostResource($post);
    }

    public function show(Post $post): PostResource
    {
        return new PostResource($post);
    }

    public function update(PostRequest $request, Post $post): PostResource
    {
        $post->update($request->validated());

        return new PostResource($post);
    }

    public function destroy(Post $post): Response
    {
        $post->delete();

        return response()->noContent();
    }
}




namespace App\Modules\Posts\Seeders;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Spatie\Permission\PermissionRegistrar;

class PostPermissionSeeder extends Seeder
{
    private null|Model|Role $defaultRole;

    public function run(): void
    {
        app()[PermissionRegistrar::class]->forgetCachedPermissions();

        $this->createDefaultRole();
        $this->createPermissions();
    }

    private function createDefaultRole(): void
    {
        $defaultRoleName = config('crudgenerator.default_role_name');
        $defaultGuardName = config('crudgenerator.default_guard_name');

        $this->defaultRole = Role::query()->firstOrCreate(['name' => $defaultRoleName], ['guard_name' => $defaultGuardName]);

        $permission = Permission::query()->firstOrCreate(['name' => $defaultRoleName]);

        $this->defaultRole->givePermissionTo($permission);
    }

    private function createPermissions(): void
    {
        $viewAny = Permission::query()->firstOrCreate(['name' => 'post.viewAny']);
        $view = Permission::query()->firstOrCreate(['name' => 'post.view']);
        $create = Permission::query()->firstOrCreate(['name' => 'post.create']);
        $update = Permission::query()->firstOrCreate(['name' => 'post.update']);
        $delete = Permission::query()->firstOrCreate(['name' => 'post.delete']);

        $this->defaultRole->givePermissionTo($viewAny, $view, $create, $update, $delete);
    }
}




namespace App\Modules\Posts\Tests\Http\Controllers;

use App\Models\User;
use App\Modules\Posts\Factories\PostFactory;
use App\Modules\Posts\Models\Post;
use App\Modules\Posts\Seeders\PostPermissionSeeder;
use Database\Factories\UserFactory;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPUnit\Framework\Attributes\DataProvider;
use Spatie\Permission\Models\Role;
use Symfony\Component\HttpFoundation\Response;
use Tests\TestCase;

class PostControllerAuthorizationTest extends TestCase
{
    use RefreshDatabase;

    public function userWithRole(string $roleName, array $attributes = []): User
    {
        (new PostPermissionSeeder)->run();

        $defaultGuardName = config('crudgenerator.default_guard_name');
        $role = Role::query()->firstOrCreate(['name' => $roleName], ['guard_name' => $defaultGuardName]);

        return UserFactory::new()->create($attributes)->assignRole($role);
    }

    #[DataProvider('roleDataProvider')]
    public function testListPostAuthorization(string $role, bool $allow): void
    {
        $user = $this->userWithRole($role);

        $response = $this->actingAs($user)->get('posts');

        $this->assertEquals($allow, $user->can('viewAny', Post::class));
        $this->assertEquals($allow, $response->getStatusCode() !== Response::HTTP_FORBIDDEN, $response->getStatusCode());
    }

    #[DataProvider('roleDataProvider')]
    public function testCreatePostAuthorization(string $role, bool $allow): void
    {
        $user = $this->userWithRole($role);

        $response = $this->actingAs($user)->post('posts');

        $this->assertEquals($allow, $user->can('create', Post::class));
        $this->assertEquals($allow, $response->getStatusCode() !== Response::HTTP_FORBIDDEN, $response->getStatusCode());
    }

    #[DataProvider('roleDataProvider')]
    public function testUpdatePostAuthorization(string $role, bool $allow): void
    {
        $user = $this->userWithRole($role);
        $post = PostFactory::new()->create();

        $response = $this->actingAs($user)->patch("posts/{$post->id}");

        $this->assertEquals($allow, $user->can('update', $post));
        $this->assertEquals($allow, $response->getStatusCode() !== Response::HTTP_FORBIDDEN, $response->getStatusCode());
    }

    #[DataProvider('roleDataProvider')]
    public function testShowPostAuthorization(string $role, bool $allow): void
    {
        $user = $this->userWithRole($role);
        $post = PostFactory::new()->create();

        $response = $this->actingAs($user)->get("posts/{$post->id}");

        $this->assertEquals($allow, $user->can('view', $post));
        $this->assertEquals($allow, $response->getStatusCode() !== Response::HTTP_FORBIDDEN, $response->getStatusCode());
    }

    #[DataProvider('roleDataProvider')]
    public function testDeletePostAuthorization(string $role, bool $allow): void
    {
        $user = $this->userWithRole($role);
        $post = PostFactory::new()->create();

        $response = $this->actingAs($user)->delete("posts/{$post->id}");

        $this->assertEquals($allow, $user->can('delete', $post));
        $this->assertEquals($allow, $response->getStatusCode() !== Response::HTTP_FORBIDDEN, $response->getStatusCode());
    }

    public static function roleDataProvider(): array
    {
        return [
            'default role with permissions is allowed' => [
                'role' => 'admin',
                'allow' => true,
            ],
            'custom role without permissions is not allowed' => [
                'role' => 'not-allowed',
                'allow' => false,
            ],
        ];
    }
}

shell 
php artisan tractor:generate Post

📂 app
📂 app-modules
 ┗ 📂 Posts
   ┗ 📂 src
     ┗ 📂 Factories
       ┗ 📄 PostFactory.php
     ┗ 📂 Filters
       ┗ 📄 PostFilter.php
     ┗ 📂 Http
       ┗ 📂 Controllers
         ┗ 📄 PostController.php
       ┗ 📂 Requests
         ┗ 📄 PostRequest.php
       ┗ 📂 Resources
         ┗ 📄 PostResource.php
     ┗ 📂 Models
       ┗ 📄 Post.php
     ┗ 📂 Policies
       ┗ 📄 PostPolicy.php
     ┗ 📂 Repositories
       ┗ 📄 PostRepository.php
     ┗ 📂 Seeders
       ┗ 📄 PostSeeder.php
   ┗ 📂 tests
     ┗ 📂 Filters
       ┗ 📄 PostFilterTest.php
     ┗ 📂 Http
       ┗ 📂 Controllers
         ┗ 📄 PostControllerAuthorizationTest.php
         ┗ 📄 PostControllerTest.php
   ┗ 📄 composer.json
   ┗ 📄 routes.php
📂 database
┗ 📂 migrations   
  ┗ 📄 2024_08_16_135340_create_posts_table.php
shell
php artisan crud:generate Post -m
shell
php artisan test