Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 17
CRAP
0.00% covered (danger)
0.00%
0 / 49
Notification
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 17
992
0.00% covered (danger)
0.00%
0 / 49
 __construct
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 fromThrowable
0.00% covered (danger)
0.00%
0 / 1
12
0.00% covered (danger)
0.00%
0 / 6
 subject
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 getSubject
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
 content
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 getContent
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
 importance
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 getImportance
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
 importanceFromLogLevelName
0.00% covered (danger)
0.00%
0 / 1
12
0.00% covered (danger)
0.00%
0 / 3
 emoji
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 getEmoji
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 1
 getException
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
 getExceptionAsString
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
 channels
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 getChannels
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
 getDefaultEmoji
0.00% covered (danger)
0.00%
0 / 1
56
0.00% covered (danger)
0.00%
0 / 12
 computeExceptionAsString
0.00% covered (danger)
0.00%
0 / 1
20
0.00% covered (danger)
0.00%
0 / 9
1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Notifier\Notification;
13
14use Psr\Log\LogLevel;
15use Symfony\Component\ErrorHandler\Exception\FlattenException;
16use Symfony\Component\Notifier\Recipient\Recipient;
17
18/**
19 * @author Fabien Potencier <fabien@symfony.com>
20 *
21 * @experimental in 5.1
22 */
23class Notification
24{
25    private const LEVELS = [
26        LogLevel::DEBUG => 100,
27        LogLevel::INFO => 200,
28        LogLevel::NOTICE => 250,
29        LogLevel::WARNING => 300,
30        LogLevel::ERROR => 400,
31        LogLevel::CRITICAL => 500,
32        LogLevel::ALERT => 550,
33        LogLevel::EMERGENCY => 600,
34    ];
35
36    public const IMPORTANCE_URGENT = 'urgent';
37    public const IMPORTANCE_HIGH = 'high';
38    public const IMPORTANCE_MEDIUM = 'medium';
39    public const IMPORTANCE_LOW = 'low';
40
41    private $channels = [];
42    private $subject = '';
43    private $content = '';
44    private $emoji = '';
45    private $exception;
46    private $exceptionAsString = '';
47    private $importance = self::IMPORTANCE_HIGH;
48
49    public function __construct(string $subject = '', array $channels = [])
50    {
51        $this->subject = $subject;
52        $this->channels = $channels;
53    }
54
55    public static function fromThrowable(\Throwable $exception, array $channels = []): self
56    {
57        $parts = explode('\\', \get_class($exception));
58
59        $notification = new self(sprintf('%s: %s', array_pop($parts), $exception->getMessage()), $channels);
60        if (class_exists(FlattenException::class)) {
61            $notification->exception = $exception instanceof FlattenException ? $exception : FlattenException::createFromThrowable($exception);
62        }
63        $notification->exceptionAsString = $notification->computeExceptionAsString($exception);
64
65        return $notification;
66    }
67
68    /**
69     * @return $this
70     */
71    public function subject(string $subject): self
72    {
73        $this->subject = $subject;
74
75        return $this;
76    }
77
78    public function getSubject(): string
79    {
80        return $this->subject;
81    }
82
83    /**
84     * @return $this
85     */
86    public function content(string $content): self
87    {
88        $this->content = $content;
89
90        return $this;
91    }
92
93    public function getContent(): string
94    {
95        return $this->content;
96    }
97
98    /**
99     * @return $this
100     */
101    public function importance(string $importance): self
102    {
103        $this->importance = $importance;
104
105        return $this;
106    }
107
108    public function getImportance(): string
109    {
110        return $this->importance;
111    }
112
113    /**
114     * @param string $level A PSR Logger log level name
115     *
116     * @return $this
117     */
118    public function importanceFromLogLevelName(string $level): self
119    {
120        $level = self::LEVELS[strtolower($level)];
121        $this->importance = $level >= 500 ? self::IMPORTANCE_URGENT : ($level >= 400 ? self::IMPORTANCE_HIGH : self::IMPORTANCE_LOW);
122
123        return $this;
124    }
125
126    /**
127     * @return $this
128     */
129    public function emoji(string $emoji): self
130    {
131        $this->emoji = $emoji;
132
133        return $this;
134    }
135
136    public function getEmoji(): string
137    {
138        return $this->emoji ?: $this->getDefaultEmoji();
139    }
140
141    public function getException(): ?FlattenException
142    {
143        return $this->exception;
144    }
145
146    public function getExceptionAsString(): string
147    {
148        return $this->exceptionAsString;
149    }
150
151    /**
152     * @return $this
153     */
154    public function channels(array $channels): self
155    {
156        $this->channels = $channels;
157
158        return $this;
159    }
160
161    public function getChannels(Recipient $recipient): array
162    {
163        return $this->channels;
164    }
165
166    protected function getDefaultEmoji(): string
167    {
168        if (!$this->exceptionAsString) {
169            return '';
170        }
171
172        switch ($this->importance) {
173            case self::IMPORTANCE_URGENT:
174                return '🌩ī¸';
175            case self::IMPORTANCE_HIGH:
176                return '🌧ī¸';
177            case self::IMPORTANCE_MEDIUM:
178                return 'đŸŒĻī¸';
179            case self::IMPORTANCE_LOW:
180            default:
181                return '⛅';
182        }
183    }
184
185    private function computeExceptionAsString(\Throwable $exception): string
186    {
187        if (class_exists(FlattenException::class)) {
188            $exception = $exception instanceof FlattenException ? $exception : FlattenException::createFromThrowable($exception);
189
190            return $exception->getAsString();
191        }
192
193        $message = \get_class($exception);
194        if ('' !== $exception->getMessage()) {
195            $message .= ': '.$exception->getMessage();
196        }
197
198        $message .= ' in '.$exception->getFile().':'.$exception->getLine()."\n";
199        $message .= "Stack trace:\n".$exception->getTraceAsString()."\n\n";
200
201        return rtrim($message);
202    }
203}