66
77use Illuminate \Support \Str ;
88use 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 ;
1013use iamfarhad \LaravelAuditLog \Models \AuditLog ;
1114use iamfarhad \LaravelAuditLog \Contracts \AuditLogInterface ;
1215use iamfarhad \LaravelAuditLog \Contracts \AuditDriverInterface ;
1316
1417final 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}
0 commit comments