1: <?php
2: /**
3: * This file is part of the Autarky package.
4: *
5: * (c) Andreas Lutro <anlutro@gmail.com>
6: *
7: * For the full copyright and license information, please view the LICENSE
8: * file that was distributed with this source code.
9: */
10:
11: namespace Autarky\Logging;
12:
13: use InvalidArgumentException;
14: use Psr\Log\AbstractLogger;
15: use Psr\Log\LoggerInterface;
16:
17: /**
18: * Manager of logging channels.
19: */
20: class ChannelManager extends AbstractLogger implements LoggerInterface
21: {
22: /**
23: * The name of the default channel to use.
24: *
25: * @var string
26: */
27: protected $defaultChannel;
28:
29: /**
30: * The defined channels.
31: *
32: * @var LoggerInterface[]
33: */
34: protected $channels = [];
35:
36: /**
37: * The deferred channel callbacks.
38: *
39: * @var callable[]
40: */
41: protected $deferredChannels = [];
42:
43: /**
44: * Constructor.
45: *
46: * @param string $defaultChannel
47: */
48: public function __construct($defaultChannel = 'default')
49: {
50: $this->defaultChannel = $defaultChannel;
51: }
52:
53: /**
54: * Change the default channel.
55: *
56: * @param string $channel
57: */
58: public function setDefaultChannel($channel)
59: {
60: $this->defaultChannel = $channel;
61: }
62:
63: /**
64: * Get the name of the default channel.
65: *
66: * @return string
67: */
68: public function getDefaultChannelName()
69: {
70: return $this->defaultChannel;
71: }
72:
73: /**
74: * Set a channel instance.
75: *
76: * @param string $channel
77: * @param LoggerInterface $logger
78: *
79: * @throws InvalidArgumentException If the channel is already defined.
80: */
81: public function setChannel($channel, LoggerInterface $logger)
82: {
83: if (isset($this->channels[$channel])) {
84: throw new InvalidArgumentException("Channel $channel is already defined");
85: }
86:
87: $this->channels[$channel] = $logger;
88: }
89:
90: /**
91: * Define a deferred channel. The callback will be invoked and the return
92: * value passed to setChannel. The return value must implement
93: * Psr\Log\LoggerInterface.
94: *
95: * @param string $channel
96: * @param callable $callback Callback that takes no arguments
97: *
98: * @throws InvalidArgumentException If the channel is already defined.
99: */
100: public function setDeferredChannel($channel, callable $callback)
101: {
102: if (isset($this->channels[$channel])) {
103: throw new InvalidArgumentException("Channel $channel is already defined");
104: }
105:
106: $this->deferredChannels[$channel] = $callback;
107: }
108:
109: /**
110: * Get a specific channel.
111: *
112: * @param string $channel Optional - if none, use default channel
113: *
114: * @return \Psr\Log\LoggerInterface
115: *
116: * @throws InvalidArgumentException If the channel is not defined.
117: */
118: public function getChannel($channel = null)
119: {
120: $channel = $channel ?: $this->defaultChannel;
121:
122: if (isset($this->deferredChannels[$channel])) {
123: $this->setChannel($channel, $this->deferredChannels[$channel]());
124: unset($this->deferredChannels[$channel]);
125: }
126:
127: if (isset($this->channels[$channel])) {
128: return $this->channels[$channel];
129: }
130:
131: throw new InvalidArgumentException("Undefined channel: $channel");
132: }
133:
134: /**
135: * {@inheritdoc}
136: */
137: public function log($level, $message, array $context = array())
138: {
139: $this->getChannel($this->defaultChannel)
140: ->log($level, $message, $context);
141: }
142: }
143: