Weave 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

Entity Command Laravel Package

wp-cli/entity-command

WP-CLI commands for managing WordPress comments, menus, options, posts, sites, terms, and users. Create, update, delete, list, and moderate entities from the command line, with support for metadata, custom fields, and block notes.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Version check first — v3.0.3 is a patch release on the 3.x line, with no breaking changes. On a phar-based install, entity-command ships bundled with WP-CLI, so you upgrade the tool rather than the package:

    wp cli update            # phar installs
    composer update wp-cli/entity-command   # only if you depend on it directly
    wp cli info              # confirm WP-CLI + PHP versions
    

    Note this release was validated against WordPress 7.1 stubs and re-enabled multisite wp site create tests on SQLite, so mixed/older WordPress installs still work but some commands now guard themselves by version.

  2. First use case — list comments for a post as JSON, then pipe into Laravel:

    wp comment list --post_id=123 --number=50 --fields=comment_ID,comment_author,comment_content --format=json
    
  3. Where to look first:

    • README.md — regenerated three times in this release (#640, #641, #649, #658); it is the canonical, up-to-date command reference. Check it before the source, especially for the newly documented wp post list / wp site list arguments.
    • wp help <command> — e.g. wp help post list now enumerates every accepted WP_Query argument.
    • features/ — Behat tests, now with fixed PHPCS violations (#652); good for expected CLI output shapes.
    • tests/ — PHPUnit coverage of the entity CRUD layer.

Implementation Patterns

Core Workflows

  1. CRUD on any entity — the same shape works for comments, posts, terms, users, sites:

    wp comment create --comment_post_ID=123 --comment_content="Test" [email protected]
    wp comment update 456 --comment_content="Revised"
    wp comment delete 456 --force
    

    user create and post update now apply parameters they previously discarded silently (#637) — see Gotchas.

  2. Querying with real WP_Query arguments — wp post list now documents every WP_Query var it accepts (#643, #645), and wp site list runs through WP_Site_Query (#639) with its arguments documented (#642). That means you can express the same filters in CLI that you would in PHP:

    wp post list --post_type=post --post_status=publish \
      --posts_per_page=20 --orderby=date --order=DESC \
      --date_query='[{"after":"2024-01-01"}]' --format=json
    wp site list --network_id=1 --site__in=2,3,4 --fields=blog_id,url,last_updated
    

    Do not reach for --fields=filter (removed from docs in #644) — filtering is expressed via the query args themselves.

  3. Meta management, including nested JSON:

    wp comment meta add 789 review_data '{"status":"pending","notes":["ok"]}' --format=json
    wp comment meta patch update 789 review_data "notes.0" "Rejected by moderation"
    wp comment meta pluck 789 review_data "status"
    

    patch/pluck take exact key paths — notes.0, not notes[0].

  4. Terms and hierarchy — Term_Command now enforces a non-negative parent ID (#662), so guard your input before it hits the CLI:

    wp term update category 12 --parent=0        # valid
    # --parent=-1 is no longer silently accepted
    
  5. User preferences and application passwords — user update editor flags are normalized to core string literals (#657), and application-password list filters now declare dash-separated aliases (#653):

    wp user update 5 --rich_editing=false --syntax_highlighting=true
    wp user application-password list 5 --user-id=5 --format=json
    wp user application-password list 5 --user_id=5 --format=json   # same filter, alias form
    
  6. Block editor icons (new in 3.0.3) — wp icon and wp icon collection (#648) let you inspect the registered icon registry from the command line. Useful when a theme/plugin registers icons and you need to confirm what's actually available:

    wp help icon
    wp icon collection list --format=json
    

    These live in the same command surface as wp block, which is now version-guarded (see Gotchas).

  7. Notes (WordPress 6.9+) — block notes are comments with comment_type=note:

    wp comment create --comment_post_ID=123 --comment_type=note \
      --comment_content="Needs review" --comment_parent=456
    

Laravel Integration

  • Use Symfony Process, not Artisan::call. Artisan::call() dispatches Laravel commands; it cannot run wp:

    use Symfony\Component\Process\Process;
    
    $process = new Process(['wp', 'comment', 'list', '--post_id=123', '--format=json', '--number=50']);
    $process->mustRun();
    $comments = json_decode($process->getOutput(), true, flags: JSON_THROW_ON_ERROR);
    

    Passing argv as an array avoids shell-quoting bugs for JSON meta values entirely.

  • Bind a thin service into the container so the wp binary path and --path/--url/--user flags live in config:

    $this->app->singleton(WpCli::class, fn () => new WpCli(
        binary: config('wordpress.wp_binary', 'wp'),
        path:   config('wordpress.abspath'),
    ));
    
  • Scheduling — run against the WordPress path explicitly, since the scheduler has no CWD context:

    $schedule->exec('wp comment delete --status=spam --force --path=/var/www/wp')
             ->dailyAt('03:00')->withoutOverlapping();
    
  • Sync into Eloquent — chunk with --number/--offset rather than pulling everything:

    foreach ($wp->listInChunks('comment', 200) as $batch) {
        Comment::upsert($batch, ['id'], ['content', 'status']);
    }
    

    Cast comment_ID explicitly; WP-CLI emits it as a string in JSON.


Gotchas and Tips

Pitfalls

  1. Silent parameter drops are fixed — audit existing scripts. #637 makes user create and post update apply arguments they previously discarded. Scripts that "worked" while ignoring, say, a role or status argument may now behave differently.

  2. --filter is no longer a documented field (#644). If anything derived a field list from the README, regenerate it. Use query args for filtering and --fields= only for real columns.

  3. Block subcommands are version-guarded (#647). On WordPress versions without the block APIs, they no longer half-run — expect an explicit "not supported" path plus quieter wp-compat false positives. Probe with wp help block at bootstrap rather than assuming availability.

  4. wp icon requires a supporting WordPress version. Treat it like wp block: feature-detect, don't hard-depend.

  5. Term parents must be ≥ 0 (#662). --parent=-1 used to slip through; sanitize to 0 for "no parent".

  6. Permissions and --user — destructive operations need capability context:

    wp comment delete 123 --force --user=admin
    

    Meta writes can fail without unfiltered_html.

  7. Multisite — site-level commands need --url or --network:

    wp comment list --network --status=spam
    wp site list --network_id=2 --fields=blog_id,url
    
  8. Performance — never run wp comment list unbounded on a large site; always pass --number (and --offset when chunking). Batch meta writes through xargs or, better, a single batched process call.

  9. Trash and replies are easy to miss — trashed comments are excluded unless --status=trash; replies need --comment_parent=<id>.

Debugging Tips

  1. Raw IDs for scripting — wp comment list --format=ids, not --porcelain (that's a create-time flag):
    wp comment list --status=spam --format=ids | xargs -r -n 50 wp comment delete --force
    
  2. Debug output:
    WP_CLI_DEBUG=1 wp comment create --comment_post_ID=123 --comment_content="Test"
    wp --debug comment list --post_id=123
    
  3. Existence checks before mutating:
    wp comment get 456 --field=comment_ID 2>/dev/null || echo "not found"
    
  4. Version-gate anything new:
    wp help icon >/dev/null 2>&1 || echo "wp icon unavailable"
    

Extension Points

  • Wrap, don't shell out ad hoc. One service class owning binary path, --path, --url, --user, and JSON decoding turns every call site into a typed array.
  • Process faking in tests — Process::fake() is what you want; $this->artisan('wp ...') does not exist:
    Process::fake([['wp', 'comment', 'list', '*'] => Process::result('[{"comment_ID":"1"}]')]);
    
  • Hooks — WP-CLI dispatches before_*/after_* hooks inside the WordPress process; if you need Laravel-side reactions, have the WP hook fire a queued job or webhook rather than trying to reach back into the app.
  • wp-cli.yml for per-project defaults so Laravel and shell invocations agree:
    path: /var/www/wp
    url: https://example.test
    

Configuration Quirks

  • Aliases — @staging, @prod are the cleanest way to target environments from Laravel config.
  • Dash vs underscore — most filters accept both (--user-id / --user_id), and #653 added the dash-separated aliases to user application-password list specifically. Prefer one form project-wide; mixing makes grep-based audits unreliable.
  • Editor preference values — post-#657 these are core string literals, so --rich_editing=false is a string "false", not a boolean; don't json_encode() a PHP false into the flag.
  • README is regenerated per release — diff it on upgrade; several behavior fixes in 3.0.3 are only visible as documentation changes.
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.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator