1<?php
2
3namespace ComboStrap;
4
5use dokuwiki\Extension\Plugin;
6
7class Message
8{
9
10
11    const SIGNATURE_CLASS = "signature";
12    const TAG = "message";
13    const TYPE_ERROR = "error";
14    private $content = [];
15    private $type;
16
17    const TYPE_INFO = 'Info';
18    const TYPE_WARNING = 'Warning';
19
20    /**
21     * @var Plugin
22     */
23    private $plugin;
24    /**
25     * @var string the page canonical
26     */
27    private $canonical = "support";
28    private $signatureName;
29
30    private $class;
31    /**
32     * @var int
33     */
34    private $status;
35
36
37    public function __construct($type)
38    {
39        $this->type = $type;
40    }
41
42    public static function createInfoMessage($plainText = null): Message
43    {
44        $message = new Message(self::TYPE_INFO);
45        if ($plainText !== null) {
46            $message->addPlainTextContent($plainText);
47        }
48        return $message;
49    }
50
51    public static function createWarningMessage($plainText = null): Message
52    {
53        $message = new Message(self::TYPE_WARNING);
54        if ($plainText !== null) {
55            $message->addPlainTextContent($plainText);
56        }
57        return $message;
58    }
59
60
61    public
62    function addContent($message, $mime): Message
63    {
64        if (!isset($this->content[$mime])) {
65            $this->content[$mime] = [];
66        }
67        $this->content[$mime][] = $message;
68        return $this;
69    }
70
71    public static function createErrorMessage(string $plainText): Message
72    {
73        $message = new Message(self::TYPE_ERROR);
74        if ($plainText !== null) {
75            $message->addPlainTextContent($plainText);
76        }
77        return $message;
78    }
79
80
81    public
82    function addHtmlContent($message): Message
83    {
84        return $this->addContent($message, Mime::HTML);
85    }
86
87    public
88    function setCanonical($canonical): Message
89    {
90        $this->canonical = $canonical;
91        return $this;
92    }
93
94    public
95    function setClass($class): Message
96    {
97        $this->class = $class;
98        return $this;
99    }
100
101    public
102    function getContent($mime = null): string
103    {
104        if ($mime != null) {
105            return implode(DOKU_LF, $this->content[$mime]);
106        }
107        $contentAll = "";
108        foreach ($this->content as $contentArray) {
109            $contentAll .= implode(DOKU_LF, $contentArray);
110        }
111        return $contentAll;
112    }
113
114    public
115    function getPlainTextContent(): ?string
116    {
117        $plainTextLines = $this->content[Mime::PLAIN_TEXT];
118        if ($plainTextLines === null) {
119            return null;
120        }
121        return implode(DOKU_LF, $plainTextLines);
122    }
123
124    public
125    function getType(): string
126    {
127        return $this->type;
128    }
129
130    public
131    function setSignatureName($signatureName): Message
132    {
133        $this->signatureName = $signatureName;
134        return $this;
135    }
136
137    /**
138     * Return an HTML Box (Used when sending message and in the main content)
139     * @return string
140     */
141    public
142    function toHtmlBox(): string
143    {
144
145        PluginUtility::getSnippetManager()->attachCssInternalStyleSheetForSlot(self::TAG);
146        $message = "";
147
148        $tagAttributes = TagAttributes::createEmpty("message")
149            ->addClassName("alert")
150            ->addOutputAttributeValue("role", "alert");
151        if ($this->class !== null) {
152            $tagAttributes->addClassName($this->class);
153        }
154        if (sizeof($this->content) <> 0) {
155
156            if ($this->getType() == Message::TYPE_INFO) {
157                $tagAttributes->addClassName("alert-success");
158            } else {
159                $tagAttributes->addClassName("alert-warning");
160            }
161
162            $message = $tagAttributes->toHtmlEnterTag("div");
163            $htmlContent = $this->getContent(Mime::HTML);
164            if ($htmlContent !== null) {
165                $message .= $htmlContent;
166            }
167
168            /**
169             * If this is a test call without a plugin
170             * we have no plugin attached
171             */
172            $firedByLang = "This message was fired by the ";
173            if ($this->plugin != null) {
174                $firedByLang = $this->plugin->getLang('message_come_from');
175            }
176
177            $message .= '<div class="' . self::SIGNATURE_CLASS . '">' . $firedByLang . PluginUtility::getDocumentationHyperLink($this->canonical, $this->signatureName, false) . '</div>';
178            $message .= '</div>';
179
180            /**
181             * In dev, to spot the XHTML compliance error
182             */
183            if (PluginUtility::isDevOrTest()) {
184                $isXml = XmlUtility::isXml($message);
185                if (!$isXml) {
186                    LogUtility::msg("This message is not xml compliant ($message)");
187                    $message = <<<EOF
188<div class='alert alert-warning'>
189    <p>This message is not xml compliant</p>
190    <pre>$message</pre>
191</div>
192EOF;
193                }
194            }
195
196        }
197        return $message;
198    }
199
200    /**
201     * This is barely used because the syntax plugin does
202     * not even inherit from {@link \dokuwiki\Extension\Plugin}
203     * but from {@link \dokuwiki\Parsing\ParserMode\Plugin}
204     * What fuck up is fucked upx
205     * @param Plugin $plugin
206     * @return $this
207     */
208    public function setPlugin(Plugin $plugin): Message
209    {
210        $this->plugin = $plugin;
211        return $this;
212    }
213
214    public function addPlainTextContent($text): Message
215    {
216        return $this->addContent($text, Mime::PLAIN_TEXT);
217    }
218
219    public function sendLogMsg()
220    {
221        $content = $this->getContent(Mime::PLAIN_TEXT);
222        switch ($this->type) {
223            case self::TYPE_WARNING:
224                $type = LogUtility::LVL_MSG_WARNING;
225                break;
226            case self::TYPE_INFO:
227                $type = LogUtility::LVL_MSG_INFO;
228                break;
229            case self::TYPE_ERROR:
230                $type = LogUtility::LVL_MSG_ERROR;
231                break;
232            default:
233                $type = LogUtility::LVL_MSG_ERROR;
234        }
235        LogUtility::msg($content, $type, $this->canonical);
236    }
237
238    public function getDocumentationHyperLink(): ?string
239    {
240        if ($this->canonical !== null) {
241            $canonicalPath = DokuPath::createFromUnknownRoot($this->canonical);
242            $label = $canonicalPath->toLabel();
243            return PluginUtility::getDocumentationHyperLink($this->canonical, $label, false);
244        } else {
245            return null;
246        }
247    }
248
249    /**
250     * An exit code / status
251     * @param int $status
252     * @return $this
253     */
254    public function setStatus(int $status): Message
255    {
256        $this->status = $status;
257        return $this;
258    }
259
260    public function getStatus(): int
261    {
262        if ($this->status !== null) {
263            return $this->status;
264        }
265        if ($this->type === null) {
266            return HttpResponse::STATUS_ALL_GOOD;
267        }
268        switch ($this->type) {
269            case self::TYPE_ERROR:
270                return HttpResponse::STATUS_INTERNAL_ERROR;
271            case self::TYPE_INFO:
272            default:
273                return HttpResponse::STATUS_ALL_GOOD;
274        }
275
276    }
277
278    public function setType(string $type): Message
279    {
280        $this->type = $type;
281        return $this;
282    }
283
284}
285