PHP code example of proai / laravel-data-integrity
1. Go to this page and download the library: Download proai/laravel-data-integrity library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
proai / laravel-data-integrity example snippets
use ProAI\DataIntegrity\AuditCase;
use ProAI\DataIntegrity\Audit;
use App\Models\Order;
class OrderAudit extends AuditCase
{
protected $model = Order::class;
public function checkTotalMatchesLineItems(): Audit
{
return $this->audit('order total matches line items')
->validate(function ($order, $fail) {
$expected = $order->lineItems()->sum('price');
if ((int) $order->total !== (int) $expected) {
$fail(
"has total {$order->total}, expected {$expected}",
fn () => $order->update(['total' => $expected]),
);
}
});
}
}
public function checkCompletedOrderHasPayment(): Audit
{
return $this->audit('completed order has a payment')
->query(fn ($query) => $query->where('status', 'completed'))
->chunkSize(200)
->validate(function ($order, $fail) {
if (! $order->payment()->exists()) {
$fail('is completed but has no payment record');
}
});
}
// Description will be "email is valid"
public function checkEmailIsValid(): Audit
{
return $this->audit()
->validate(fn ($user, $fail) => /* ... */);
}
use Closure;
use Illuminate\Database\Eloquent\Model;
use ProAI\DataIntegrity\IntegrityCheck;
class BelongsToExists implements IntegrityCheck
{
public function __construct(
public readonly string $relation,
) {}
public function description(): string
{
return "{$this->relation} exists";
}
public function validate(Model $model, Closure $fail): void
{
if (! $model->{$this->relation}()->exists()) {
$foreignKey = $model->{$this->relation}()->getForeignKeyName();
$fail("references missing {$this->relation} ({$foreignKey}: {$model->$foreignKey})");
}
}
}
class CommentAudit extends AuditCase
{
protected $model = Comment::class;
public function checkPostExists(): Audit
{
return $this->auditUsing(BelongsToExists::class, ['post']);
}
public function checkAuthorExists(): Audit
{
return $this->auditUsing(BelongsToExists::class, ['author']);
}
}
class CachedCountIsCorrect implements IntegrityCheck
{
public function __construct(
public readonly string $relation,
public readonly string $column,
) {}
public function validate(Model $model, Closure $fail): void
{
$expected = $model->{$this->relation}()->count();
if ($model->{$this->column} !== $expected) {
$fail(
"has {$this->column} {$model->{$this->column}}, expected {$expected}",
fn () => $model->update([$this->column => $expected]),
);
}
}
}
// In ThreadAudit
public function checkPostsCount(): Audit
{
return $this->auditUsing(CachedCountIsCorrect::class, ['posts', 'posts_count']);
}
public function checkSubscribersCount(): Audit
{
return $this->auditUsing(CachedCountIsCorrect::class, ['subscribers', 'subscribers_count']);
}
class CachedCountIsCorrect implements IntegrityCheck
{
protected Collection $expectedCounts;
public function __construct(
public readonly string $relation,
public readonly string $column,
) {}
public function before(EloquentCollection $chunk): void
{
$example = $chunk->first()->{$this->relation}();
$foreignKey = $example->getForeignKeyName();
$table = $example->getRelated()->getTable();
$this->expectedCounts = DB::table($table)
->whereIn($foreignKey, $chunk->modelKeys())
->groupBy($foreignKey)
->pluck(DB::raw('count(*)'), $foreignKey);
}
public function validate(Model $model, Closure $fail): void
{
$expected = $this->expectedCounts->get($model->getKey(), 0);
if ($model->{$this->column} !== $expected) {
$fail(
"has {$this->column} {$model->{$this->column}}, expected {$expected}",
fn () => $model->update([$this->column => $expected]),
);
}
}
}
use ProAI\DataIntegrity\AuditManager;
AuditManager::register('posts-count', PostsCountIsCorrect::class);
public function checkPostsCount(): Audit
{
return $this->auditUsing('posts-count');
}
use ProAI\DataIntegrity\AuditManager;
// Override the default chunk size (default: 1000)
AuditManager::defaultChunkSize(500);
// Override the audit discovery path (default: database/audits)
AuditManager::discoverIn(database_path('my-audits'));
public function validate(Model $model, Closure $fail): void;
$fail(string $reason, ?Closure $fix = null): void
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.