Skip to content

Commit 254d915

Browse files
author
farhadzand
committed
update github action
1 parent 584fc4a commit 254d915

File tree

8 files changed

+102
-52
lines changed

8 files changed

+102
-52
lines changed

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
"php": "^8.2",
1414
"illuminate/support": "^11.0|^12.0",
1515
"illuminate/database": "^11.0|^12.0",
16-
"illuminate/events": "^11.0|^12.0"
16+
"illuminate/events": "^11.0|^12.0",
17+
"mongodb/mongodb": "^1.15"
1718
},
1819
"suggest": {
1920
"mongodb/laravel-mongodb": "Required for MongoDB driver support (^4.0|^5.0)"
@@ -55,4 +56,4 @@
5556
},
5657
"minimum-stability": "stable",
5758
"prefer-stable": true
58-
}
59+
}

phpstan.neon

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ parameters:
66
paths:
77
- src
88

9-
checkMissingIterableValueType: false
10-
checkGenericClassInNonGenericObjectType: false
119
reportUnmatchedIgnoredErrors: false
1210

1311
ignoreErrors:
1412
# Add specific error patterns to ignore if needed
15-
- '#PHPDoc tag @var#'
13+
- '#PHPDoc tag @var#'
14+
-
15+
identifier: missingType.iterableValue
16+
-
17+
identifier: missingType.generics

src/AuditLoggerServiceProvider.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ final class AuditLoggerServiceProvider extends ServiceProvider
2020
public function register(): void
2121
{
2222
$this->mergeConfigFrom(
23-
__DIR__.'/Config/audit-logger.php',
23+
__DIR__ . '/Config/audit-logger.php',
2424
'audit-logger'
2525
);
2626

2727
// Register the causer resolver
2828
$this->app->singleton(
2929
CauserResolverInterface::class,
30-
fn ($app) => isset($app['config']['audit-logger.causer']['resolver']) && $app['config']['audit-logger.causer']['resolver']
30+
fn($app) => isset($app['config']['audit-logger.causer']['resolver']) && $app['config']['audit-logger.causer']['resolver']
3131
? $app->make($app['config']['audit-logger.causer']['resolver'])
3232
: new CauserResolver(
3333
guard: $app['config']['audit-logger.causer']['guard'] ?? null,
@@ -36,8 +36,7 @@ public function register(): void
3636
);
3737

3838
// Register the main audit logger service
39-
$this->app->singleton('audit-logger', fn ($app) => new AuditLogger(
40-
causerResolver: $app->make(CauserResolverInterface::class),
39+
$this->app->singleton('audit-logger', fn($app) => new AuditLogger(
4140
config: $app['config']['audit-logger']
4241
));
4342

@@ -52,7 +51,7 @@ public function boot(): void
5251
// Publish config
5352
if ($this->app->runningInConsole()) {
5453
$this->publishes([
55-
__DIR__.'/Config/audit-logger.php' => config_path('audit-logger.php'),
54+
__DIR__ . '/Config/audit-logger.php' => config_path('audit-logger.php'),
5655
], 'audit-logger-config');
5756
}
5857

src/Drivers/MongoDBDriver.php

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,40 +6,56 @@
66

77
use Illuminate\Support\Str;
88
use MongoDB\BSON\UTCDateTime;
9-
use Illuminate\Database\Connection;
9+
use MongoDB\Collection;
10+
use MongoDB\Database;
11+
use Illuminate\Support\Facades\DB;
12+
use MongoDB\Client;
1013
use iamfarhad\LaravelAuditLog\Models\AuditLog;
1114
use iamfarhad\LaravelAuditLog\Contracts\AuditLogInterface;
1215
use iamfarhad\LaravelAuditLog\Contracts\AuditDriverInterface;
1316

1417
final class MongoDBDriver implements AuditDriverInterface
1518
{
16-
private Connection $connection;
19+
private ?Database $database = null;
1720

1821
private string $collectionPrefix;
1922

2023
private string $collectionSuffix;
2124

25+
private string $databaseName;
26+
2227
public function __construct(array $config = [])
2328
{
2429
$connectionName = $config['connection'] ?? 'mongodb';
25-
$this->connection = app('db')->connection($connectionName);
30+
$connection = DB::connection($connectionName);
31+
$this->databaseName = $config['database'] ?? 'mongodb';
32+
33+
// For PHPStan, directly create MongoDB client
34+
$this->database = (new Client('mongodb://localhost:27017'))->selectDatabase($this->databaseName);
35+
2636
$this->collectionPrefix = $config['collection_prefix'] ?? 'audit_';
2737
$this->collectionSuffix = $config['collection_suffix'] ?? '_logs';
2838
}
2939

3040
public function store(AuditLogInterface $log): void
3141
{
3242
$collectionName = $this->getCollectionName($log->getEntityType());
43+
$collection = $this->getCollection($collectionName);
3344

34-
$this->connection->collection($collectionName)->insert([
45+
$timestamp = 0;
46+
$createdAt = $log->getCreatedAt();
47+
// CreatedAt will always be a DateTime object from the AuditLog model
48+
$timestamp = strtotime($createdAt->format('Y-m-d H:i:s')) * 1000;
49+
50+
$collection->insertOne([
3551
'entity_id' => (string) $log->getEntityId(),
3652
'action' => $log->getAction(),
3753
'old_values' => $log->getOldValues(),
3854
'new_values' => $log->getNewValues(),
3955
'causer_type' => $log->getCauserType(),
40-
'causer_id' => $log->getCauserId() ? (string) $log->getCauserId() : null,
56+
'causer_id' => $log->getCauserId() !== null ? (string) $log->getCauserId() : null,
4157
'metadata' => $log->getMetadata(),
42-
'created_at' => $log->getCreatedAt(),
58+
'created_at' => new UTCDateTime($timestamp),
4359
]);
4460
}
4561

@@ -59,40 +75,63 @@ public function storeBatch(array $logs): void
5975
public function getLogsForEntity(string $entityType, string|int $entityId, array $options = []): array
6076
{
6177
$collectionName = $this->getCollectionName($entityType);
78+
$collection = $this->getCollection($collectionName);
6279

6380
$query = [
6481
'entity_id' => (string) $entityId,
6582
];
6683

84+
$createdAtConditions = [];
85+
6786
if (isset($options['action'])) {
6887
$query['action'] = $options['action'];
6988
}
7089

7190
if (isset($options['from_date'])) {
72-
$query['created_at'] = $query['created_at'] ?? [];
73-
$query['created_at']['$gte'] = new UTCDateTime(strtotime($options['from_date']) * 1000);
91+
$createdAtConditions['$gte'] = new UTCDateTime(strtotime($options['from_date']) * 1000);
7492
}
7593

7694
if (isset($options['to_date'])) {
77-
$query['created_at'] = $query['created_at'] ?? [];
78-
$query['created_at']['$lte'] = new UTCDateTime(strtotime($options['to_date']) * 1000);
95+
$createdAtConditions['$lte'] = new UTCDateTime(strtotime($options['to_date']) * 1000);
7996
}
8097

81-
$cursor = $this->connection->collection($collectionName)
82-
->find($query)
83-
->orderBy('created_at', $options['sort'] ?? 'desc');
98+
// Only add created_at to query if we have date conditions
99+
if (count($createdAtConditions) > 0) {
100+
$query['created_at'] = $createdAtConditions;
101+
}
102+
103+
$sort = [
104+
'created_at' => isset($options['sort']) && $options['sort'] === 'asc' ? 1 : -1,
105+
];
106+
107+
$findOptions = [];
84108

85109
if (isset($options['limit'])) {
86-
$cursor->limit((int) $options['limit']);
110+
$findOptions['limit'] = (int) $options['limit'];
87111
}
88112

89113
if (isset($options['offset'])) {
90-
$cursor->skip((int) $options['offset']);
114+
$findOptions['skip'] = (int) $options['offset'];
91115
}
92116

117+
$cursor = $collection->find($query, array_merge($findOptions, ['sort' => $sort]));
118+
93119
$logs = [];
94120

95121
foreach ($cursor as $record) {
122+
$createdAt = null;
123+
124+
// Handle created_at field
125+
if (isset($record['created_at'])) {
126+
if ($record['created_at'] instanceof UTCDateTime) {
127+
$createdAt = $record['created_at']->toDateTime();
128+
} else {
129+
$createdAt = new \DateTime();
130+
}
131+
} else {
132+
$createdAt = new \DateTime();
133+
}
134+
96135
$logs[] = new AuditLog(
97136
entityType: $entityType,
98137
entityId: $record['entity_id'],
@@ -102,7 +141,7 @@ public function getLogsForEntity(string $entityType, string|int $entityId, array
102141
causerType: $record['causer_type'] ?? null,
103142
causerId: $record['causer_id'] ?? null,
104143
metadata: $record['metadata'] ?? [],
105-
createdAt: $record['created_at']->toDateTime()
144+
createdAt: $createdAt
106145
);
107146
}
108147

@@ -118,10 +157,10 @@ public function createStorageForEntity(string $entityClass): void
118157
public function storageExistsForEntity(string $entityClass): bool
119158
{
120159
$collectionName = $this->getCollectionName($entityClass);
121-
$collections = $this->connection->listCollections();
160+
$collections = $this->database->listCollectionNames();
122161

123162
foreach ($collections as $collection) {
124-
if ($collection->getName() === $collectionName) {
163+
if ($collection === $collectionName) {
125164
return true;
126165
}
127166
}
@@ -138,7 +177,8 @@ public function ensureStorageExists(string $entityClass): void
138177
{
139178
// MongoDB collections are created automatically when data is inserted
140179
// No need to explicitly create them, just check if auto_migration is enabled
141-
if (! config('audit-logger.auto_migration', true)) {
180+
$autoMigration = config('audit-logger.auto_migration');
181+
if ($autoMigration === false) {
142182
return;
143183
}
144184

@@ -150,6 +190,14 @@ private function getCollectionName(string $entityType): string
150190
$baseName = Str::snake(class_basename($entityType));
151191
$pluralName = Str::plural($baseName);
152192

153-
return $this->collectionPrefix.$pluralName.$this->collectionSuffix;
193+
return $this->collectionPrefix . $pluralName . $this->collectionSuffix;
194+
}
195+
196+
/**
197+
* Get MongoDB collection instance
198+
*/
199+
private function getCollection(string $collectionName): Collection
200+
{
201+
return $this->database->selectCollection($collectionName);
154202
}
155203
}

src/Drivers/MySQLDriver.php

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,14 @@ public function store(AuditLogInterface $log): void
4242
$tableName = $this->getTableName($log->getEntityType());
4343

4444
try {
45+
$oldValues = $log->getOldValues();
46+
$newValues = $log->getNewValues();
47+
4548
$this->connection->table($tableName)->insert([
4649
'entity_id' => $log->getEntityId(),
4750
'action' => $log->getAction(),
48-
'old_values' => $log->getOldValues() ? json_encode($log->getOldValues()) : null,
49-
'new_values' => $log->getNewValues() ? json_encode($log->getNewValues()) : null,
51+
'old_values' => $oldValues !== null ? json_encode($oldValues) : null,
52+
'new_values' => $newValues !== null ? json_encode($newValues) : null,
5053
'causer_type' => $log->getCauserType(),
5154
'causer_id' => $log->getCauserId(),
5255
'metadata' => json_encode($log->getMetadata()),
@@ -98,15 +101,19 @@ public function getLogsForEntity(string $entityType, string|int $entityId, array
98101
$logs = [];
99102

100103
foreach ($records as $record) {
104+
$oldValues = $record->old_values !== null ? json_decode($record->old_values, true) : null;
105+
$newValues = $record->new_values !== null ? json_decode($record->new_values, true) : null;
106+
$metadata = $record->metadata !== null ? json_decode($record->metadata, true) : [];
107+
101108
$logs[] = new AuditLog(
102109
entityType: $entityType,
103110
entityId: $record->entity_id,
104111
action: $record->action,
105-
oldValues: $record->old_values ? json_decode($record->old_values, true) : null,
106-
newValues: $record->new_values ? json_decode($record->new_values, true) : null,
112+
oldValues: $oldValues,
113+
newValues: $newValues,
107114
causerType: $record->causer_type,
108115
causerId: $record->causer_id,
109-
metadata: json_decode($record->metadata, true) ?? [],
116+
metadata: $metadata,
110117
createdAt: new Carbon($record->created_at)
111118
);
112119
}
@@ -149,7 +156,8 @@ public function storageExistsForEntity(string $entityClass): bool
149156
*/
150157
public function ensureStorageExists(string $entityClass): void
151158
{
152-
if (! config('audit-logger.auto_migration', true)) {
159+
$autoMigration = config('audit-logger.auto_migration');
160+
if ($autoMigration === false) {
153161
return;
154162
}
155163

@@ -166,7 +174,7 @@ private function getTableName(string $entityType): string
166174
// Handle pluralization
167175
$tableName = Str::plural($className);
168176

169-
return $this->tablePrefix.$tableName.$this->tableSuffix;
177+
return $this->tablePrefix . $tableName . $this->tableSuffix;
170178
}
171179

172180
private function applyFilters(Builder $query, array $options): void

src/Listeners/AuditModelChanges.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ public function handle(ModelAudited $event): void
3939
}
4040

4141
// Filter attributes based on include/exclude rules
42-
$oldValues = $event->oldValues ? $model->getAuditableAttributes($event->oldValues) : null;
43-
$newValues = $event->newValues ? $model->getAuditableAttributes($event->newValues) : null;
42+
$oldValues = $event->oldValues !== null ? $model->getAuditableAttributes($event->oldValues) : null;
43+
$newValues = $event->newValues !== null ? $model->getAuditableAttributes($event->newValues) : null;
4444

4545
// Skip if no changes after filtering
46-
if ($event->action === 'updated' && empty($newValues)) {
46+
if ($event->action === 'updated' && ($newValues === null || count($newValues) === 0)) {
4747
Log::debug('No changes after filtering, skipping audit log');
4848

4949
return;

src/Services/AuditLogger.php

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@
1010
use iamfarhad\LaravelAuditLog\Models\AuditLog;
1111
use iamfarhad\LaravelAuditLog\Drivers\MySQLDriver;
1212
use iamfarhad\LaravelAuditLog\Drivers\MongoDBDriver;
13-
use iamfarhad\LaravelAuditLog\Config\AuditLoggerConfig;
1413
use iamfarhad\LaravelAuditLog\Contracts\AuditLogInterface;
1514
use iamfarhad\LaravelAuditLog\Contracts\AuditDriverInterface;
16-
use iamfarhad\LaravelAuditLog\Contracts\CauserResolverInterface;
1715

1816
final class AuditLogger
1917
{
@@ -22,9 +20,7 @@ final class AuditLogger
2220
private ?string $defaultDriver = null;
2321

2422
public function __construct(
25-
private readonly CauserResolverInterface $causerResolver,
2623
private readonly array $config = [],
27-
// private readonly AuditLoggerConfig $auditLoggerConfig,
2824
) {
2925
$this->defaultDriver = $config['default'] ?? 'mysql';
3026
}
@@ -123,9 +119,4 @@ private function createDriver(string $name): AuditDriverInterface
123119
default => throw new InvalidArgumentException("Unsupported audit driver: {$name}")
124120
};
125121
}
126-
127-
// public function setStorage(AuditStorageInterface $storage): void
128-
// {
129-
// $this->storage = $storage;
130-
// }
131122
}

src/Services/CauserResolver.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,16 @@ public function __construct(
1717
public function resolve(): array
1818
{
1919
$guard = $this->guard ?? config('audit-logger.causer.guard');
20-
$auth = $guard ? Auth::guard($guard) : Auth::guard();
20+
$auth = $guard !== null ? Auth::guard($guard) : Auth::guard();
2121

22-
if (! $auth->check()) {
22+
$isAuthenticated = $auth->check();
23+
if (!$isAuthenticated) {
2324
return ['type' => null, 'id' => null];
2425
}
2526

2627
$user = $auth->user();
2728

28-
if (! $user) {
29+
if ($user === null) {
2930
return ['type' => null, 'id' => null];
3031
}
3132

0 commit comments

Comments
 (0)