Difference between revisions of "Using Models"

From WHMCS Documentation

m (DOCS-6461 - Broken link on "Using Models" docs page)
 
(3 intermediate revisions by 3 users not shown)
Line 1: Line 1:
WHMCS 6.0 introduces a code-driven method for interacting with data stored in the database. Many tables in the WHMCS installation are modeled as classes available both internally to WHMCS and to third party code. These classes, based on the Eloquent 4.1 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.
+
<div class="docs-alert-info">
 +
We introduced models in WHMCS 6.0.
 +
</div>
  
A model-based class in WHMCS corresponds to a single table in the database and has properties that map to the columns in that table. For instance, the <tt>\WHMCS\User\Client</tt> class models data in the <tt>tblclients</tt> table. It includes the properties <tt>$id</tt>, <tt>$firstName</tt>, <tt>$lastName</tt>, and others that map to the <tt>id</tt>, <tt>firstname</tt>, <tt>lastname</tt>, and other 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 <tt>$domains</tt> and <tt>$contacts</tt> properties contain collections of <tt>\WHMCS\Domain\Domain</tt> and <tt>\WHMCS\User\Client\Contact</tt> instances, which in turn model data in the <tt>tbldomains</tt> and <tt>tblcontacts</tt> tables, and each have their own column and relational properties.  
+
Models offer a code-driven method for interacting with data stored in the database. Many tables in WHMCS are modeled as classes available both internally to WHMCS and to third-party code. These classes are based on 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.
  
This page describes basic interactivity with model classes. Please see [http://laravel.com/docs/eloquent Laravel's Eloquent ORM manual] for a much more detailed reference.
+
A model-based class in WHMCS corresponds to a single table in the database and has properties that map to the columns in that table. For example, the <tt>\WHMCS\User\Client</tt> class models data in the <tt>tblclients</tt> table. It includes the properties <tt>$id</tt>, <tt>$firstName</tt>, <tt>$lastName</tt>, and others that map to <tt>id</tt>, <tt>firstname</tt>, <tt>lastname</tt>, and other 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 <tt>$domains</tt> and <tt>$contacts</tt> properties contain collections of <tt>\WHMCS\Domain\Domain</tt> and <tt>\WHMCS\User\Client\Contact</tt> instances, which in turn model data in the <tt>tbldomains</tt> and <tt>tblcontacts</tt> tables. Each have their own column and relational properties.  
  
=Creating Records=
+
For a detailed reference, see [http://laravel.com/docs/eloquent Laravel's Eloquent ORM manual].
  
Creating new records using model-based classes is as simple as creating a local object.
+
For more information about WHMCS databases, see [https://developers.whmcs.com/advanced/db-interaction/ Interacting With The Database].
 +
 
 +
== Creating Records ==
 +
 
 +
Creating new records using model-based classes requires you to create a local object.
 +
 
 +
To do this:
  
 
# Declare a new instance of the class of data to insert.
 
# Declare a new instance of the class of data to insert.
Line 13: Line 21:
 
# Call the <tt>save()</tt> method to insert the new record into the database.
 
# Call the <tt>save()</tt> method to insert the new record into the database.
  
Models with a primary key have that key automatically populated on save. In most model-based classes the <tt>$id</tt> property is the classes' primary key. As with all all backend interaction it's helpful to place the <tt>save()</tt> call in a <tt>try</tt>/<tt>catch</tt> block to intelligently handle any error situations.
+
Models with a primary key have that key automatically populated on save. In most model-based classes, the <tt>$id</tt> property is the classes' primary key. Place the <tt>save()</tt> call in a <tt>try</tt>/<tt>catch</tt> block to intelligently handle any error situations.
  
 
<syntaxhighlight lang="php">
 
<syntaxhighlight lang="php">
Line 33: Line 41:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=Retrieving Records=
+
== Retrieving Records ==
  
 
Use a model's static <tt>find()</tt> method to locate a record by its primary key. <tt>find()</tt> retrieves the record or returns <tt>null</tt> if the record doesn't exist in the database. Alternatively, use the static <tt>findOrFail()</tt> method to throw an exception instead of retuning a null value if the record isn't found.
 
Use a model's static <tt>find()</tt> method to locate a record by its primary key. <tt>find()</tt> retrieves the record or returns <tt>null</tt> if the record doesn't exist in the database. Alternatively, use the static <tt>findOrFail()</tt> method to throw an exception instead of retuning a null value if the record isn't found.
Line 70: Line 78:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Once models are retrieved then their related properties to other models are also immediately available. Relational model properties in turn have other relational properties that can be chained together in multiple ways.
+
Once models are retrieved, their related properties to other models are also immediately available. Relational model properties in turn have other relational properties that can be chained together in multiple ways.
  
 
<syntaxhighlight lang="php">
 
<syntaxhighlight lang="php">
Line 88: Line 96:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=Updating Records=
+
== Updating Records ==
  
 
A model's <tt>save()</tt> method can also update existing records in addition to creating new records.  
 
A model's <tt>save()</tt> method can also update existing records in addition to creating new records.  
Line 117: Line 125:
 
=Deleting Records=
 
=Deleting Records=
  
Call a model object's <tt>delete()</tt> method to delete its associated table row. Deletions are permanent and cannot be undone.
+
Call a model object's <tt>delete()</tt> method to delete its associated table row. Deletions are permanent and irreversible.
  
 
<syntaxhighlight lang="php">
 
<syntaxhighlight lang="php">
Line 148: Line 156:
 
     echo "Take that, domain!";
 
     echo "Take that, domain!";
 
} catch (Exception $e) {
 
} catch (Exception $e) {
     echo "Uh oh. I couldn't delete John Doe's first domain. {$e->getMessage()}";
+
     echo "I couldn't delete John Doe's first domain. {$e->getMessage()}";
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
Line 154: Line 162:
 
=Current Models=
 
=Current Models=
  
Not every table in WHMCS has an associated model yet. These are the current model classes in WHMCS and their associated tables. This list is updated on new version releases. Please check here often for new functionality.
+
WHMCS includes many models. When you refactor legacy code that references database tables, we recommend that you attempt to locate a corresponding model to replace it with using the keywords in the table's literal name.
 
 
{| class="wikitable"
 
! Table
 
! Class
 
|-
 
| tblaccounts
 
| <tt>\WHMCS\Billing\Payment\Transaction</tt>
 
|-
 
| tbladmins
 
| <tt>\WHMCS\User\Admin</tt>
 
|-
 
| tbladminsecurityquestions
 
| <tt>\WHMCS\User\Client\SecurityQuestion</tt>
 
|-
 
| tblaffiliates
 
| <tt>\WHMCS\User\Client\Affiliate</tt>
 
|-
 
| tblannouncements
 
| <tt>\WHMCS\Announcement\Announcement</tt>
 
|-
 
| tblcancelrequests
 
| <tt>\WHMCS\Service\CancellationRequest</tt>
 
|-
 
| tblclients
 
| <tt>\WHMCS\User\Client</tt>
 
|-
 
| tblcontacts
 
| <tt>\WHMCS\User\Client\Contact</tt>
 
|-
 
| tbldomains
 
| <tt>\WHMCS\Domain\Domain</tt>
 
|-
 
| tbldomainsadditionalfields
 
| <tt>\WHMCS\Domain\AdditionalField</tt>
 
|-
 
| tbldownloadcats
 
| <tt>\WHMCS\Download\Category</tt>
 
|-
 
| tbldownloads
 
| <tt>\WHMCS\Download\Download</tt>
 
|-
 
| tblemailtemplates
 
| <tt>\WHMCS\Mail\Template</tt>
 
|-
 
| tblhosting
 
| <tt>\WHMCS\Service\Service</tt>
 
|-
 
| tblhostingaddons
 
| <tt>\WHMCS\Service\Addon</tt>
 
|-
 
| tblinvoices
 
| <tt>\WHMCS\Billing\Invoice</tt>
 
|-
 
| tblnetworkissues
 
| <tt>\WHMCS\Network\NetworkIssue</tt>
 
|-
 
| tblproductgroups
 
| <tt>\WHMCS\Product\Group</tt>
 
|-
 
| tblproducts
 
| <tt>\WHMCS\Product\Product</tt>
 
|-
 
| tblquoteitems
 
| <tt>\WHMCS\Billing\Quote\Item</tt>
 
|-
 
| tblquotes
 
| <tt>\WHMCS\Billing\Quote</tt>
 
|-
 
|}
 
 
 
=See Also=
 
* [[Interacting With The Database]]
 

Latest revision as of 20:18, 13 May 2022

We introduced models in WHMCS 6.0.

Models offer a code-driven method for interacting with data stored in the database. Many tables in WHMCS are modeled as classes available both internally to WHMCS and to third-party code. These classes are based on 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.

A model-based class in WHMCS corresponds to a single table in the database and has 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 properties $id, $firstName, $lastName, and others that map to id, firstname, lastname, and other 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 in turn model data in the tbldomains and tblcontacts tables. Each have their own column and relational properties.

For a detailed reference, see Laravel's Eloquent ORM manual.

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.

Models with a primary key have that key automatically populated on save. In most model-based classes, the $id property is the classes' 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 = 'jdoe@example.org';

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 record isn't found.

<?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}.";
}

Once models are retrieved, their related properties to other models are also immediately available. Relational model properties in turn have other relational properties that can be chained together 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 and irreversible.

<?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()}";
}

Current Models

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