diff options
| author | Asko Nõmm <asko@nth.ee> | 2024-11-15 17:58:47 +0200 |
|---|---|---|
| committer | Asko Nõmm <asko@nth.ee> | 2024-11-15 17:58:47 +0200 |
| commit | 0cdfa63b9ce75e5db1e05d2332d6cab667a9f7e1 (patch) | |
| tree | 314ab8b5d749650d9da362212b7f0e63db38ddba | |
| parent | bac7b24d9a1fe3d7b8dd68102794f786f7c43000 (diff) | |
Implement interpolation
| -rw-r--r-- | README.md | 12 | ||||
| -rw-r--r-- | src/Loggr.php | 57 | ||||
| -rw-r--r-- | tests/LoggrTest.php | 17 |
3 files changed, 83 insertions, 3 deletions
@@ -22,11 +22,19 @@ Loggr is very simple to use, and looks like this: ```php $loggr = new Loggr(new FileSystemDriver('path-to-logs')); -$loggr->info('context'); +$loggr->info('message', ['some-data' => 'goes-here']); ``` All you have to do is instantiate Loggr with the appropriate driver for your use case and then simply -log away with any data you want to give it. It takes scalar values, as well as arrays and objects. +log away with any data you want to give it. As per the PSR-3 standard, you can also interpolate context values +into the message placeholder, like so: + +```php +$loggr = new Loggr(new FileSystemDriver('path-to-logs')); +$loggr->info('Hello {who}', ['who' => 'World']); +``` + +Which would then output `Hello World` as the message. ### Methods diff --git a/src/Loggr.php b/src/Loggr.php index 82d5681..e641a18 100644 --- a/src/Loggr.php +++ b/src/Loggr.php @@ -50,12 +50,67 @@ class Loggr implements LoggerInterface $this->driver->log($this->format->serialize(new Message( level: $level, trace: $this->trace, - content: $message, + content: $this->interpolate($message, $context), context: $context, ))); } /** + * @param string $message + * @param mixed|null $context + * @return string + */ + private function interpolate(string $message, mixed $context = null): string + { + // $context has to be present, an array or an object. + if (!is_array($context) && !is_object($context)) return $message; + + /** @var string|null $parsed_message */ + $parsed_message = preg_replace_callback('/{(?<var>.*?)}/', function ($matches) use ($context) { + return $this->parseInterpolation($matches['var'], $context); + }, $message); + + if ($parsed_message === null) { + $this->error = "Error parsing interpolation."; + return $message; + } + + return $parsed_message; + } + + /** + * @param string $var + * @param mixed|null $context + * @return string + */ + private function parseInterpolation(string $var, mixed $context = null): string + { + $parts = explode('.', $var); + $value = $context; + + foreach ($parts as $part) { + if (is_array($value) && array_key_exists($part, $value)) { + $value = $value[$part]; + continue; + } + + if (is_object($value) && property_exists($value, $part)) { + $value = $value->{$part}; + continue; + } + + return ''; + } + + return match(gettype($value)) { + 'string' => $value, + 'integer', 'boolean', 'double' => (string)$value, + 'NULL' => 'null', + default => '' + }; + } + + /** * Logs an emergency level message with optional context. * * @param string|\Stringable $message diff --git a/tests/LoggrTest.php b/tests/LoggrTest.php index a7c3628..2172907 100644 --- a/tests/LoggrTest.php +++ b/tests/LoggrTest.php @@ -4,6 +4,7 @@ namespace Asko\Loggr\Tests; use Asko\Loggr\Drivers\OutputDriver; use Asko\Loggr\Loggr; +use DateTime; use PHPUnit\Framework\TestCase; class LoggrTest extends TestCase @@ -22,4 +23,20 @@ class LoggrTest extends TestCase $loggr->info('test'); $this->assertEquals("Driver or format not set.", $loggr->error); } + + public function testInterpolation(): void + { + $full_date = (new DateTime())->format('Y-m-d H:i:s'); + $this->expectOutputString("[{$full_date}] LoggrTest.INFO: test something - {\"interpolation\":\"something\"}"); + $loggr = new Loggr(new OutputDriver()); + $loggr->info('test {interpolation}', ['interpolation' => 'something']); + } + + public function testNestedInterpolation(): void + { + $full_date = (new DateTime())->format('Y-m-d H:i:s'); + $this->expectOutputString("[{$full_date}] LoggrTest.INFO: test something - {\"nested\":{\"interpolation\":\"something\"}}"); + $loggr = new Loggr(new OutputDriver()); + $loggr->info('test {nested.interpolation}', ['nested' => ['interpolation' => 'something']]); + } }
\ No newline at end of file |
