summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md12
-rw-r--r--src/Loggr.php57
-rw-r--r--tests/LoggrTest.php17
3 files changed, 83 insertions, 3 deletions
diff --git a/README.md b/README.md
index b19e38b..dcefc94 100644
--- a/README.md
+++ b/README.md
@@ -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