@@ -100,9 +100,10 @@ public function removeLogGuild(
100100 unset($ this ->log_channel_ids [$ guild_id ]);
101101 }
102102
103- public static function getPartDifferences (object $ newPart , ?object $ oldPart ): array
103+ public function getPartDifferences (object $ newPart , ?object $ oldPart ): array
104104 {
105105 if (! $ oldPart ) return [];
106+ if ($ newPart instanceof Message) return $ this ->handleMessages ($ newPart , $ this ->discord , $ oldPart );
106107 if (!method_exists ($ newPart , 'getRawAttributes ' ) || !method_exists ($ oldPart , 'getRawAttributes ' )) return [];
107108
108109 $ differences = [];
@@ -127,7 +128,7 @@ public static function getPartDifferences(object $newPart, ?object $oldPart): ar
127128 $ removedItems = array_diff ($ oldItems , $ newItems );
128129 if (!empty ($ addedItems ) || !empty ($ removedItems )) $ differences [$ key ] = ['added ' => $ addedItems , 'removed ' => $ removedItems ];
129130 } elseif (is_object ($ newValue ) && is_object ($ oldValue )) {
130- $ nestedDifferences = self :: getPartDifferences ($ newValue , $ oldValue );
131+ $ nestedDifferences = $ this -> getPartDifferences ($ newValue , $ oldValue );
131132 if (!empty ($ nestedDifferences )) $ differences [$ key ] = $ nestedDifferences ;
132133 } elseif ($ newValue !== $ oldValue ) $ differences [$ key ] = ['new ' => $ newValue , 'old ' => $ oldValue ];
133134 } else $ differences [$ key ] = ['new ' => $ newValue , 'old ' => null ];
@@ -138,14 +139,61 @@ public static function getPartDifferences(object $newPart, ?object $oldPart): ar
138139 return self ::removeRedundantProperties ($ differences );
139140 }
140141
142+ public function handleMessages (mixed $ message , Discord $ discord , ?Message $ oldMessage )
143+ {
144+ if (
145+ ! $ message instanceof Message ||
146+ $ message ->author ->id === $ discord ->id ||
147+ $ message ->author ->bot ||
148+ ! $ message ->guild
149+ ) {
150+ return [];
151+ }
152+
153+ $ oldMessage = $ oldMessage ;
154+
155+ if (! $ oldMessage || trim ($ message ->content ) === trim ($ oldMessage ->content )) {
156+ return ;
157+ }
158+
159+ return $ this ->diff ($ oldMessage ->content , $ message ->content );
160+ }
161+
162+ /**
163+ * Get the difference between two strings.
164+ */
165+ public function diff (string $ before , string $ after ): array
166+ {
167+ $ beforeLines = array_map ('trim ' , explode (PHP_EOL , trim ($ before )));
168+ $ afterLines = array_map ('trim ' , explode (PHP_EOL , trim ($ after )));
169+
170+ $ beforeDiff = array_map (static fn ($ line , $ index ) =>
171+ isset ($ afterLines [$ index ])
172+ ? ($ line === $ afterLines [$ index ] ? " {$ line }" : "- {$ line }" )
173+ : "- {$ line }" ,
174+ $ beforeLines , array_keys ($ beforeLines ));
175+
176+ $ afterDiff = array_map (static fn ($ line , $ index ) =>
177+ isset ($ beforeLines [$ index ])
178+ ? ($ line === $ beforeLines [$ index ] ? " {$ line }" : "+ {$ line }" )
179+ : "+ {$ line }" ,
180+ $ afterLines , array_keys ($ afterLines ));
181+
182+ return [
183+ 'old ' => "```diff " . PHP_EOL . implode (PHP_EOL , $ beforeDiff ) . PHP_EOL . "``` " ,
184+ 'new ' => "```diff " . PHP_EOL . implode (PHP_EOL , $ afterDiff ) . PHP_EOL . "``` " ,
185+ ];
186+ }
187+
188+
141189 public static function removeRedundantProperties (array $ array ): array
142190 {
143191 return array_diff_key ($ array , array_flip (self ::REDUNDANT_PREOPRTIES ));
144192 }
145193
146194 public function getDifferences ($ newObject , $ oldObject ): array
147195 {
148- return self :: getPartDifferences ($ newObject , $ oldObject );
196+ return $ this -> getPartDifferences ($ newObject , $ oldObject );
149197 }
150198
151199 private static function arrayRecursiveDiff (array $ array1 , array $ array2 ): array
@@ -218,40 +266,42 @@ public function logEvent(
218266 string $ event ,
219267 string $ guild_id ,
220268 object |string $ content ,
221- object $ old_content = null
269+ object $ old_content = null ,
270+ ?MessageBuilder $ builder = null
222271 ): PromiseInterface
223272 {
273+ if (! $ channel_id = $ this ->log_channel_ids [$ guild_id ] ?? null ) return reject (new \Exception ('Discord Channel ID not configured ' ));
274+ if (! $ guild = $ discord ->guilds ->get ('id ' , $ guild_id )) return reject (new \Exception ('Discord Guild not found ' ));
275+ if (! $ channel = $ guild ->channels ->get ('id ' , $ channel_id )) return reject (new \Exception ('Discord Channel not found ' ));
276+ if (! $ builder ) $ builder = MessageBuilder::new ();
277+
224278 $ differences = $ this ->getDifferences ($ content , $ old_content );
225279 $ discord ->getLogger ()->info ("Logging event: $ event, Guild ID: {$ guild_id }, Differences: " . json_encode ($ differences ), [
226280 'event ' => $ event ,
227281 'guild_id ' => $ guild_id ,
228282 'differences ' => $ differences
229283 ]);
230284
231- if (! $ channel_id = $ this ->log_channel_ids [$ guild_id ] ?? null ) return reject (new \Exception ('Discord Channel ID not configured ' ));
232- if (! $ guild = $ discord ->guilds ->get ('id ' , $ guild_id )) return reject (new \Exception ('Discord Guild not found ' ));
233- if (! $ channel = $ guild ->channels ->get ('id ' , $ channel_id )) return reject (new \Exception ('Discord Channel not found ' ));
234-
235- if (is_string ($ content )) return $ channel ->sendMessage (MessageBuilder::new ()->setContent ($ content ));
285+ if (is_string ($ content )) return $ channel ->sendMessage ($ builder ->setContent ($ content ));
236286
237287 $ description = '' ;
238- if (!empty ($ differences )) {
288+ if (! empty ($ differences )) {
239289 foreach ($ differences as $ key => $ diff ) {
240290 if (is_array ($ diff )) {
241291 if (isset ($ diff ['added ' ]) && !empty ($ diff ['added ' ])) $ description .= "$ key added: " . json_encode ($ diff ['added ' ]) . PHP_EOL ;
242292 if (isset ($ diff ['removed ' ]) && !empty ($ diff ['removed ' ])) $ description .= "$ key removed: " . json_encode ($ diff ['removed ' ]) . PHP_EOL ;
243293 if (isset ($ diff ['new ' ]) && isset ($ diff ['old ' ])) {
244294 $ description .= "$ key changed: " . PHP_EOL ;
245- $ description .= " Old: ` { $ diff ['old ' ]} ` " . PHP_EOL ;
246- $ description .= " New: ` { $ diff ['new ' ]} ` " . PHP_EOL ;
295+ $ description .= ' Old: ' . PHP_EOL . $ diff ['old ' ] . PHP_EOL ;
296+ $ description .= ' New: ' . PHP_EOL . $ diff ['new ' ] . PHP_EOL ;
247297 }
248- } else $ description .= "$ key: " . json_encode ( $ diff) . PHP_EOL ;
298+ } else $ description .= "$ key: " . PHP_EOL . $ diff . PHP_EOL ;
249299 }
250- } else $ description = is_object ($ content ) ? json_encode ($ content ) : (is_array ($ content ) ? json_encode ($ content ) : $ content );
300+ } // else $description = is_object($content) ? json_encode($content) : (is_array($content) ? json_encode($content) : $content);
251301
252302 if (! $ description ) return reject (new \Exception ('No content to log ' ));
253- if (strlen ($ description ) <= 4096 ) return $ channel ->sendMessage (MessageBuilder:: new () ->addEmbed (EmbedBuilder::new ($ discord , $ this ->color , $ this ->footer )->setDescription ($ description )->setTitle ($ event )));
254- return $ channel ->sendMessage (MessageBuilder:: new () ->addFileFromContent ("$ event.txt " , $ description ));
303+ if (strlen ($ description ) <= 4096 ) return $ channel ->sendMessage ($ builder ->addEmbed (EmbedBuilder::new ($ discord , $ this ->color , $ this ->footer )->setDescription ($ description )->setTitle ($ event )));
304+ return $ channel ->sendMessage ($ builder ->addFileFromContent ("$ event.txt " , $ description ));
255305 }
256306
257307 /*
0 commit comments