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