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

Cpanel Php Laravel Package

gufy/cpanel-php

A PHP client for the cPanel API that simplifies common hosting tasks like managing email accounts, databases, FTP users, and files. Framework-agnostic, with support for cPanel API 2 and UAPI, it lets you integrate cPanel management into any PHP app.

View on GitHub
Deep Wiki
Context7

Getting Started

gufy/cpanel-php is a thin PHP wrapper around the cPanel API 2 (UAPI) and WHM API 1 HTTP endpoints. It is not a Laravel package in the modern sense — no published config, no facade, no first‑party service provider — but it is straightforward to wire up.

Install

composer require gufy/cpanel-php

Minimal boot

The class is constructed with an options array and then called with execute():

use Gufy\CpanelPhp\Cpanel;

$cpanel = new Cpanel([
    'host'      => env('CPANEL_HOST'),      // full URL incl. scheme + port
    'username'  => env('CPANEL_USERNAME'),
    'password'  => env('CPANEL_PASSWORD'),  // password OR API token
    'auth_type' => env('CPANEL_AUTH_TYPE'), // 'basic' or 'hash'
    'timeout'   => 60,
]);

// WHM call — runs as the account in `username` (typically root / reseller)
$cpanel->execute('listaccts');

Where to look first

  1. README.md — shows the constructor options and the two call styles (WHM vs. per‑cPanel‑account).
  2. src/Cpanel.php — the whole surface is here: setHost, setPort, setUsername, setPassword, setAuthType, setTimeout, setMethod, setCpanelUser, setModule, setFunction, execute, getResponse. Read it end to end; it's small.
  3. The official cPanel docs for the specific function you call (https://api.docs.cpanel.net/) — the wrapper does no validation, so the function/module names are your responsibility.

First useful use case

Account provisioning from a Laravel admin panel: create a cPanel account with createacct, list accounts with listaccts, or manage a single account's mailboxes via the UAPI Email::list_pops. Anything that would otherwise be a manual cPanel click is a good fit.

Implementation Patterns

Wrap it — don't call it from controllers. The class is stateful (fluent setters mutate the instance) and returns raw payloads. Bind a single configured instance in a service provider and expose intent‑revealing methods:

// app/Services/WhmClient.php
class WhmClient
{
    public function __construct(private Cpanel $cpanel) {}

    public function listAccounts(): array
    {
        $res = $this->cpanel->execute('listaccts');
        return $this->unwrap($res)['acct'] ?? [];
    }

    public function createAccount(string $user, string $domain, string $plan, string $pass): array
    {
        return $this->unwrap($this->cpanel->execute('createacct', [
            'username' => $user,
            'domain'   => $domain,
            'plan'     => $plan,
            'password' => $pass,
        ]));
    }
}

Config via environment, never code. Put the host, credentials, and auth type in config/cpanel.php, read from env(), and cache the config. Store tokens with Laravel's encrypted cast or a secrets manager; never commit them.

Two distinct auth/context modes:

  • WHM mode — host ends in :2087 (or :2086 if not TLS), username is root or a reseller, auth_type is basic with the root password or hash with a WHM API token.
  • cPanel mode — host ends in :2083 / :2082, username is the cPanel user, and you must call setCpanelUser($user) before setModule(...)->setFunction(...)->execute(). Mixing these up returns generic 401/403s that are painful to debug.

Prefer API tokens over root passwords. WHM API tokens are created per user and can be revoked. For anything user‑facing (e.g. a customer managing their own mailboxes), generate a token scoped to that cPanel user and hand it to a client configured for :2083.

Queue long operations. createacct, restorepkg, transfer and backups take seconds to minutes. Dispatch a job, log the outcome, and notify on failure. The class is not async and has a fixed timeout.

Integrate with Laravel features:

  • Use an Artisan command (php artisan cpanel:sync) for bulk reconciliation — it's the easiest way to run against a list of accounts with ->setCpanelUser().
  • Store API results in a local table (accounts, disk usage, mailbox counts) rather than hitting the API on every page load.
  • Use events (AccountCreated, MailboxQuotaChanged) around the wrapper so side effects are testable.

Testing: the client ultimately uses Guzzle. Extract the HTTP layer or inject a mocked Cpanel into your service and assert on the arguments passed to execute(). If you need HTTP‑level tests, use Guzzle's MockHandler via a refactored client, since the package doesn't expose a pluggable handler.

Gotchas and Tips

  • The package is archived. Stars are modest (~157) and it has no dependents or active maintainers. Treat it as a stable utility, not a living dependency. Pin the version ("gufy/cpanel-php": "^1.0") and expect to fork or replace it if cPanel changes its API shape. Read the code once; it's a few hundred lines and you may end up owning it.
  • host must include the scheme and port. 'https://server:2087' works; 'server:2087' and 'https://server' do not. This is the #1 cause of "it silently does nothing."
  • auth_type must match the credential. basic sends a password; hash sends the token as the password. Using a token with basic (or vice versa) yields 401/403 responses that look like network errors in the logs.
  • Function vs. module vs. user are separate setters. For UAPI calls you need all three:
    $cpanel->setCpanelUser('bob')
           ->setModule('Email')
           ->setFunction('add_pop')
           ->execute(['email' => '[email protected]', 'password' => '...', 'quota' => 500]);
    
    Forgetting setCpanelUser on a WHM‑mode client falls back to the reseller's own context and can create resources in the wrong account — a security‑relevant bug.
  • Responses are heterogeneous. WHM often returns {"result": [...], "metadata": {...}}; UAPI returns {"result": {...}, "status": 1}. The wrapper does not normalize. Always inspect for status/result before using the data, and throw a domain exception when status !== 1.
  • Errors are split between HTTP and application layers. A 200 with status: 0 means the API rejected you; a GuzzleHttp\Exception\ClientException or ServerException means transport/route failure. Catch both, log the full response body, and rethrow as a typed exception.
  • No retries, no rate limiting. cPanel/WHM will throttle bursts. If you're looping listaccts per user, add a small sleep or a queued job with RateLimited middleware in Laravel 10+.
  • Timeouts default around 30s. Bump it for pkgacct/backup calls, and set the same value on Guzzle's client options if you fork — the wrapper forwards the timeout.
  • Logging: enable Guzzle logging only in local dev. API tokens end up in Authorization headers and request logs; scrub them before they reach your log store.
  • Extension points are limited to subclassing Cpanel and overriding execute() or the request builder. If you need connection pooling, retries, circuit breaking, or a proper Laravel integration, that is the intended seam — subclass and wrap, don't monkey‑patch.
  • Testing trick: since credentials live in the constructor array, a small factory (Cpanel::class binding in AppServiceProvider) makes it trivial to swap in a fake client in feature tests and avoid network calls entirely.
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.
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
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums