Models

Models offer a code-driven method for interacting with data in the database. Many tables in WHMCS are available as modeled classes, both internally, to WHMCS, and externally, to third-party code.

These classes in WHMCS use the Eloquent ORM library, model tables, columns, and relationships between tables in WHMCS’ backend database. Use these classes to easily interact with WHMCS’ backend data without the need for complex SQL statements.

When you refactor legacy code that references database tables, we recommend that you attempt to locate a corresponding model to replace it with models using the keywords in the table’s literal name.

Model-Based Classes

Model-based classes in WHMCS each correspond to a single table in the database and have properties that map to the columns in that table. For example, the \WHMCS\User\Client class models data in the tblclients table. It includes the $id, $firstName, and $lastName properties and other properties that map to columns in that table.

Model-based classes also have properties that relate to other model-based classes. For example, a client can have more than one domain or contact on their account. The client’s $domains and $contacts properties contain collections of \WHMCS\Domain\Domain and \WHMCS\User\Client\Contact instances, which model data in the tbldomains and tblcontacts tables. Each has their own column and relational properties.

For more information about WHMCS databases, see Interacting With The Database.

Creating Records

Creating new records using model-based classes requires you to create a local object.

To do this:

  1. Declare a new instance of the class of data to insert.
  2. Populate the object’s properties.
  3. Call the save() method to insert the new record into the database.

The system automatically populates models with a primary key on save. In most model-based classes, the $id property is the class’s primary key. Place the save() call in a try{} catch{} block to intelligently handle any error situations.

<?php

use WHMCS\User\Client;

$newClient = new Client;
$newClient->firstName = 'John';
$newClient->lastName = 'Doe';
$newClient->email = '[email protected]';

try {
    $newClient->save();
    echo "I just created John Doe's client record. His id number is {$newClient->id}.";
} catch (Exception $e) {
    echo "Uh oh. I couldn't create John Doe's client record. {$e->getMessage()}";
}

Retrieving Records

Use a model’s static find() method to locate a record by its primary key. find() retrieves the record or returns null if the record doesn’t exist in the database. Alternatively, use the static findOrFail() method to throw an exception instead of retuning a null value if the system cannot find the record.

<?php

use WHMCS\User\Client;

$clientId = 1234;

// Look for John Doe by id. $johnDoe will be null if id 1234 doesn't exist.
$johnDoe = Client::find($clientId);

// Look for John Doe by id, but throw an exception if id 1234 doesn't exist.
try {
    $johnDoe = Client::findOrFail($clientId);
} catch (Exception $e) {
    echo "I couldn't find John Doe. {$e->getMessage()}";
}

Querying for data is also possible with chains of where() method calls. Call it statically first with the names of the property and value to search for. End the chain with a get() method call to query the database and retrieve a collection of the results.

<?php

use WHMCS\User\Client;

// Look for all clients with the name "John Doe".
$johnDoes = Client::where('firstName', 'John')->where('lastName', 'Doe')->get();

foreach ($johnDoes as $john) {
    echo "I found a John Doe from {$john->city}, {$john->state} with the id number {$client->id}.";
}

After the system retrieves models, their properties are immediately available to other models. Relational model properties have other relational properties that you can combine in multiple ways.

<?php

use WHMCS\User\Client;

$clientId = 1234;
$johnDoe = Client::find($clientId);

echo 'John Doe has ' . $johnDoe->services->count() . ' service(s).';
echo 'John Doe also has ' . $johnDoe->contacts->count() . ' contacts. The first one goes by ' . $johnDoe->contacts->first()->firstName . '.';

foreach ($johnDoe->services as $service) {
    echo 'Service ' . $service->domain . ' is based from the product ' . $service->product->name . '.';
}

Updating Records

A model’s save() method can also update existing records in addition to creating new records.

<?php

use WHMCS\User\Client;

$clientId = 1234;

try {
    $johnDoe = Client::findOrFail($clientId);

    $johnDoe->address1 = '1234 Main Street';
    $johnDoe->city = 'Anytown';
    $johnDoe->state = 'TX';
    $johnDoe->postcode = '12345';

    $johnDoe->save();

    echo "I've updated John Doe's address.";
} catch (Exception $e) {
    echo "Uh oh. I couldn't update John Doe's address. {$e->getMessage()}";
}

Deleting Records

Call a model object’s delete() method to delete its associated table row.

Deletions are permanent.

<?php

use WHMCS\User\Client;

$clientId = 1234;

try {
    Client::findOrFail($clientId)->delete();
    echo "So long, John!";
} catch (Exception $e) {
    echo "Uh oh. I couldn't delete John Doe's client record. {$e->getMessage()}";
}

It is also possible to delete an object’s related properties:

<?php

use WHMCS\User\Client;

$clientId = 1234;

try {
    // Delete John Doe's first domain.
    Client::findOrFail($clientId)->domains->first()->delete();
    echo "Take that, domain!";
} catch (Exception $e) {
    echo "I couldn't delete John Doe's first domain. {$e->getMessage()}";
}

Last modified: June 5, 2024