Skip to content

Commit c767577

Browse files
committed
chore: updates readme
1 parent 4ae8722 commit c767577

File tree

1 file changed

+151
-3
lines changed

1 file changed

+151
-3
lines changed

README.md

Lines changed: 151 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ A library for a simple model structure.
88
* [Configuration](#configuration)
99
* [Creating a model](#creating-a-model)
1010
* [Interacting with a model](#interacting-with-a-model)
11+
* [Attribute validation](#attribute-validation)
1112
* [Data transfer objects](#data-transfer-objects)
1213
* [Classes of note](#classes-of-note)
1314
* [Model](#model)
@@ -57,7 +58,9 @@ Models are classes that hold data and provide some helper methods for interactin
5758

5859
### A simple model
5960

60-
This is an example of a model that just holds properties.
61+
This is an example of a model that just holds properties. Properties can be defined in two ways:
62+
63+
#### Using the shorthand syntax:
6164

6265
```php
6366
namespace Boomshakalaka\Whatever;
@@ -70,14 +73,43 @@ class Breakfast_Model extends Model {
7073
*/
7174
protected static $properties = [
7275
'id' => 'int',
73-
'name' => 'string',
76+
'name' => ['string', 'Default Name'], // With default value
7477
'price' => 'float',
7578
'num_eggs' => 'int',
7679
'has_bacon' => 'bool',
7780
];
7881
}
7982
```
8083

84+
#### Using property definitions for more control:
85+
86+
```php
87+
namespace Boomshakalaka\Whatever;
88+
89+
use Boomshakalaka\StellarWP\Models\Model;
90+
use Boomshakalaka\StellarWP\Models\ModelPropertyDefinition;
91+
92+
class Breakfast_Model extends Model {
93+
/**
94+
* @inheritDoc
95+
*/
96+
protected static function properties(): array {
97+
return [
98+
'id' => ModelPropertyDefinition::create()
99+
->type('int')
100+
->required(),
101+
'name' => ModelPropertyDefinition::create()
102+
->type('string')
103+
->default('Default Name')
104+
->nullable(),
105+
'price' => ModelPropertyDefinition::create()
106+
->type('float')
107+
->requiredOnSave(),
108+
];
109+
}
110+
}
111+
```
112+
81113
### A ReadOnly model
82114

83115
This is a model whose intent is to only read and store data. The Read operations should - in most cases - be deferred to
@@ -183,6 +215,115 @@ class Breakfast_Model extends Model implements Contracts\ModelCrud {
183215
}
184216
```
185217

218+
## Interacting with a model
219+
220+
### Change tracking
221+
222+
Models track changes to their properties and provide methods to manage those changes:
223+
224+
```php
225+
$breakfast = new Breakfast_Model([
226+
'name' => 'Original Name',
227+
'price' => 5.99,
228+
]);
229+
230+
// Check if a property is dirty (changed)
231+
$breakfast->setAttribute('name', 'New Name');
232+
if ($breakfast->isDirty('name')) {
233+
echo 'Name has changed!';
234+
}
235+
236+
// Get all dirty values
237+
$dirtyValues = $breakfast->getDirty(); // ['name' => 'New Name']
238+
239+
// Commit changes (makes current values the "original")
240+
$breakfast->commitChanges();
241+
// or use the alias:
242+
$breakfast->syncOriginal();
243+
244+
// Revert a specific property change
245+
$breakfast->setAttribute('price', 7.99);
246+
$breakfast->revertChange('price'); // price is back to 5.99
247+
248+
// Revert all changes
249+
$breakfast->setAttribute('name', 'Another Name');
250+
$breakfast->setAttribute('price', 8.99);
251+
$breakfast->revertChanges(); // All properties back to original
252+
253+
// Get original value
254+
$originalName = $breakfast->getOriginal('name');
255+
$allOriginal = $breakfast->getOriginal(); // Get all original values
256+
```
257+
258+
### Checking if properties are set
259+
260+
The `isSet()` method checks if a property has been set. This is different from PHP's `isset()` because it considers `null` values and default values as "set":
261+
262+
```php
263+
$breakfast = new Breakfast_Model();
264+
265+
// Properties with defaults are considered set
266+
if ($breakfast->isSet('name')) { // true if 'name' has a default value
267+
echo 'Name is set';
268+
}
269+
270+
// Properties without defaults are not set until assigned
271+
if (!$breakfast->isSet('price')) { // false - no default and not assigned
272+
echo 'Price is not set';
273+
}
274+
275+
// Setting a property to null still counts as set
276+
$breakfast->setAttribute('price', null);
277+
if ($breakfast->isSet('price')) { // true - explicitly set to null
278+
echo 'Price is set (even though it\'s null)';
279+
}
280+
281+
// PHP's isset() behaves differently with null
282+
if (!isset($breakfast->price)) { // false - isset() returns false for null
283+
echo 'PHP isset() returns false for null values';
284+
}
285+
```
286+
287+
**Key differences from PHP's `isset()`:**
288+
- `isSet()` returns `true` for properties with default values
289+
- `isSet()` returns `true` for properties explicitly set to `null`
290+
- `isSet()` returns `false` only for properties that have no default and haven't been assigned
291+
292+
### Creating models from query data
293+
294+
Models can be created from database query results using the `fromData()` method:
295+
296+
```php
297+
// From an object or array
298+
$data = DB::get_row("SELECT * FROM breakfasts WHERE id = 1");
299+
$breakfast = Breakfast_Model::fromData($data);
300+
301+
// With different build modes
302+
$breakfast = Breakfast_Model::fromData($data, Breakfast_Model::BUILD_MODE_STRICT);
303+
$breakfast = Breakfast_Model::fromData($data, Breakfast_Model::BUILD_MODE_IGNORE_MISSING);
304+
$breakfast = Breakfast_Model::fromData($data, Breakfast_Model::BUILD_MODE_IGNORE_EXTRA);
305+
```
306+
307+
Build modes:
308+
- `BUILD_MODE_STRICT`: Throws exceptions for missing or extra properties
309+
- `BUILD_MODE_IGNORE_MISSING`: Ignores properties missing from the data
310+
- `BUILD_MODE_IGNORE_EXTRA`: Ignores extra properties in the data (default)
311+
312+
### Extending model construction
313+
314+
Models can perform custom initialization after construction by overriding the `afterConstruct()` method:
315+
316+
```php
317+
class Breakfast_Model extends Model {
318+
protected function afterConstruct() {
319+
// Perform custom initialization
320+
if ($this->has_bacon && $this->num_eggs > 2) {
321+
$this->setAttribute('name', $this->name . ' (Hearty!)');
322+
}
323+
}
324+
}
325+
```
326+
186327
## Attribute validation
187328

188329
Sometimes it would be helpful to validate attributes that are set in the model. To do that, you can create `validate_*()`
@@ -442,6 +583,13 @@ $breakfast = Breakfast_Model::find( 1 );
442583
$breakfast->delete();
443584
```
444585

586+
### Unsetting properties
587+
588+
```php
589+
$breakfast = Breakfast_Model::find( 1 );
590+
unset($breakfast->price); // Unsets the price property
591+
```
592+
445593
## Classes of note
446594

447595
### `Model`
@@ -455,7 +603,7 @@ This is an abstract class to extend for creating model factories.
455603
### `ModelQueryBuilder`
456604

457605
This class extends the [`stellarwp/db`](https://github.com/stellarwp/db) `QueryBuilder` class so that it returns
458-
model instances rather than arrays or `stdClass` instances. Using this requires models that implement the `ModelFromQueryBuilderObject`
606+
model instances rather than arrays or `stdClass` instances. Using this requires models that implement the `ModelBuildsFromData`
459607
interface.
460608

461609
### `DataTransferObject`

0 commit comments

Comments
 (0)