Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Corcel Laravel Package

jgrossi/corcel

Eloquent-based models to query a WordPress database directly from Laravel or any Composer PHP app. Use WordPress as the CMS/admin backend while your app consumes posts, pages, taxonomies, options, menus, users, ACF fields, attachments, and more.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation (Laravel 12+):

    composer require jgrossi/corcel
    

    Add the service provider to config/app.php (Laravel 12+ auto-discovers providers, but explicit declaration remains valid):

    'providers' => [
        // ...
        Jgrossi\Corcel\CorcelServiceProvider::class,
    ],
    
  2. Configuration: Publish the config file:

    php artisan vendor:publish --provider="Jgrossi\Corcel\CorcelServiceProvider"
    

    Update .env with your WordPress site URL and API credentials (prefer Application Passwords):

    CORCEL_WORDPRESS_URL=https://your-wordpress-site.com
    CORCEL_APP_PASSWORD=your_application_password  # Recommended over CORCEL_PASSWORD
    CORCEL_APP_NAME=YourAppName
    
  3. First Use Case (Laravel 12+): Fetch a post by ID with improved type safety:

    use Jgrossi\Corcel\Models\Post;
    
    $post = Post::find(1);
    echo $post->title->render(); // Uses Laravel 12's enhanced stringable output
    

Implementation Patterns

Core Workflows

  1. CRUD Operations (Optimized for Laravel 12):

    // Create (Laravel 12's mass assignment protection applies)
    $post = Post::create([
        'title' => 'New Post',
        'content' => 'Hello, WordPress!',
        'status' => 'draft' // Explicit status handling
    ]);
    
    // Update (uses Laravel 12's model events)
    $post->update(['title' => 'Updated Title']);
    
    // Delete (soft deletes supported)
    $post->delete(); // Returns deleted model
    
  2. Relationships (Enhanced with Laravel 12's relationship improvements):

    // Define relationship (Laravel 12's relationship macros work)
    public function author()
    {
        return $this->belongsTo(User::class, 'author_id')
            ->withDefault(); // Handle missing relationships gracefully
    }
    
    // Eager loading (Laravel 12's query builder optimizations)
    $posts = Post::with('author', 'categories')->get();
    
  3. Media Handling (Streamlined for Laravel 12's filesystem):

    use Illuminate\Support\Facades\Storage;
    
    $media = Media::create([
        'file' => Storage::disk('s3')->putFile('uploads', 'image.jpg'),
        'alt_text' => 'Image Alt Text',
    ]);
    
  4. Taxonomies (Laravel 12's collection methods):

    $post->categories()->sync([1, 2, 3]);
    
    // Get taxonomy terms as collections
    $terms = $post->tags()->get();
    $terms->each(fn($term) => $term->name);
    

Integration Tips

  • Laravel 12 Events: Leverage new event system:

    use Jgrossi\Corcel\Events\PostSaved;
    
    PostSaved::dispatch($post)
        ->then(fn() => Log::info('Post saved via Corcel'));
    
  • Middleware: Use Laravel 12's enhanced middleware stack:

    Corcel::middleware(function ($request) {
        // Custom middleware logic
        return $request->header('X-Custom-Header') === 'allowed';
    });
    
  • Custom Endpoints: Extend with Laravel 12's HTTP client:

    Corcel::extend('custom', function () {
        return new class {
            public function get($id)
            {
                return Corcel::http()->get("/wp-json/custom/v1/items/{$id}");
            }
        };
    });
    

Gotchas and Tips

Pitfalls

  1. Authentication:

    • Application Passwords Required: Plain CORCEL_PASSWORD is deprecated. Use CORCEL_APP_PASSWORD for security.
    • Permission Checks: Non-admin users may still face endpoint restrictions despite authentication.
  2. Caching:

    • Laravel 12 Cache: Corcel now uses Laravel's cache system by default. Clear with:
      php artisan cache:clear
      php artisan corcel:clear-cache
      
    • Tagged Caching: Use cache tags for better invalidation:
      $post = Post::find(1, ['tags' => ['posts']]);
      
  3. Model Binding:

    • Improved Type Safety: Laravel 12's route model binding works seamlessly:
      route('posts.show', function (Post $post) { // Type-hinted model
          return $post->title;
      });
      
  4. REST API Limits:

    • Rate Limiting: Handle 429 errors with Laravel 12's retry mechanism:
      try {
          $post = Post::find(1);
      } catch (RateLimitExceeded $e) {
          $e->retryAfter(function () {
              return now()->addSeconds(5);
          });
      }
      

Debugging

  • Laravel 12 Debugging Tools:

    • Enable debug mode in config/corcel.php:
      'debug' => env('CORCEL_DEBUG', false),
      
    • Use Laravel's built-in debugging:
      php artisan tinker
      >>> \Jgrossi\Corcel\Facades\Corcel::debug();
      
  • Logging:

    • Log raw API responses with Laravel's logging channels:
      Corcel::enableLogging('single'); // Logs to 'single' channel
      

Extension Points

  1. Custom Models (Laravel 12's model enhancements):

    namespace App\Models;
    
    use Jgrossi\Corcel\Models\Post;
    use Illuminate\Database\Eloquent\Concerns\HasUuids;
    
    class Post extends Post
    {
        use HasUuids; // Laravel 12's UUID support
    
        protected $casts = [
            'date' => 'datetime:Y-m-d',
        ];
    }
    
  2. API Extensions (Laravel 12's HTTP client):

    Corcel::extend('wp-graphql', function () {
        return new class {
            public function query($query)
            {
                return Corcel::http()->post('/wp-graphql', [
                    'json' => ['query' => $query],
                ]);
            }
        };
    });
    
  3. Hooks (Laravel 12's event system):

    use Jgrossi\Corcel\Facades\Corcel;
    
    Corcel::hook('wp_loaded', function () {
        // Your logic
    });
    
    // Or use Laravel events
    event(new \Jgrossi\Corcel\Events\WordPressLoaded);
    
  4. Laravel 12 Features:

    • Model Observers: Use Laravel's observers for WordPress models:
      Post::observe(PostObserver::class);
      
    • Resource Classes: Convert Corcel models to API resources:
      namespace App\Http\Resources;
      
      use Jgrossi\Corcel\Models\Post;
      use Illuminate\Http\Resources\Json\JsonResource;
      
      class PostResource extends JsonResource
      {
          public function toArray($request)
          {
              return [
                  'title' => $this->title->render(),
                  'url' => route('posts.show', $this),
              ];
          }
      }
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor