Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
5.56% covered (danger)
5.56%
2 / 36
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
BotTextImageFunction
5.56% covered (danger)
5.56%
2 / 36
50.00% covered (danger)
50.00%
2 / 4
48.28
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFunctionName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 functionBodyCore
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
12
 functionBodyImpl
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3declare(strict_types=1);
4
5namespace PeServer\Core\Mvc\Template\Plugin;
6
7use Throwable;
8use PeServer\Core\Image\Alignment;
9use PeServer\Core\Collection\Arr;
10use PeServer\Core\Binary;
11use PeServer\Core\CoreDefines;
12use PeServer\Core\Cryptography;
13use PeServer\Core\Html\HtmlDocument;
14use PeServer\Core\Image\Graphics;
15use PeServer\Core\Image\ImageSetting;
16use PeServer\Core\Image\ImageType;
17use PeServer\Core\Image\Point;
18use PeServer\Core\Image\Rectangle;
19use PeServer\Core\Image\Color\RgbColor;
20use PeServer\Core\Image\HorizontalAlignment;
21use PeServer\Core\Image\Size;
22use PeServer\Core\Image\TextSetting;
23use PeServer\Core\Image\VerticalAlignment;
24use PeServer\Core\Mvc\Template\Plugin\TemplateFunctionBase;
25use PeServer\Core\Mvc\Template\Plugin\TemplatePluginArgument;
26use PeServer\Core\OutputBuffer;
27use PeServer\Core\IO\Path;
28use PeServer\Core\Text;
29use PeServer\Core\Throws\TemplateException;
30use PeServer\Core\Throws\Throws;
31use PeServer\Core\TypeUtility;
32
33/**
34 * Bot用にテキストから画像生成。
35 *
36 * 一旦ただの文字列画像化で、botに対して何の効力もないけどインターフェイス的なところでここに集約させたいのでこのままリリース。
37 * まぁ最低限の処理くらいは捌けるでしょ。
38 *
39 * $params
40 *  * text: 画像化するテキスト。
41 *  * alt: 代替文言(いらんかもね)。
42 *  * width: 指定時の横幅(現状 未指定は 100)。
43 *  * height: 指定時の高さ(現状 未指定は 100)。
44 *  * font-size: ホントサイズ(未指定は 12.0)。
45 *  * background-color: 背景色
46 *  * foreground-color: 前景色
47 *  * obfuscate-level: 難読化(未指定は 0 )。 未実装。
48 */
49class BotTextImageFunction extends TemplateFunctionBase
50{
51    #region define
52
53    private const HASH_ALGORITHM = 'sha256';
54
55    #endregion
56
57    public function __construct(TemplatePluginArgument $argument)
58    {
59        parent::__construct($argument);
60    }
61
62    #region TemplateFunctionBase
63
64    public function getFunctionName(): string
65    {
66        return 'bot_text_image';
67    }
68
69    private function functionBodyCore(): string
70    {
71        /** @var string */
72        $text = $this->params['text'] ?? Text::EMPTY;
73        /** @var string */
74        $alt = $this->params['alt'] ?? Text::EMPTY;
75        /**
76         * @var int
77         * @phpstan-var positive-int
78         */
79        $width = (int)($this->params['width'] ?? 100);
80        /**
81         * @var int
82         * @phpstan-var positive-int
83         */
84        $height = (int)($this->params['height'] ?? 100);
85        /** @var float */
86        $fontSize = (float)($this->params['font-size'] ?? 12.5);
87        /** @var string */
88        $className = $this->params['class'] ?? Text::EMPTY;
89        /** @var string */
90        $backgroundColorText = $this->params['background-color'] ?? '#eeeeee';
91        $backgroundColor = RgbColor::fromHtmlColorCode($backgroundColorText);
92        /** @var string */
93        $foregroundColorText = $this->params['foreground-color'] ?? '#0f0f0f';
94        $foregroundColor = RgbColor::fromHtmlColorCode($foregroundColorText);
95        $obfuscateLevel = TypeUtility::parseBoolean($this->params['obfuscate-level'] ?? 0);
96
97        $size = new Size($width, $height);
98        $fontFilePath = CoreDefines::DEFAULT_FONT_FILE_PATH;
99        $textSetting = new TextSetting(HorizontalAlignment::Center, VerticalAlignment::Center, $fontFilePath, 0);
100
101        $image = Graphics::create($size);
102        $image->setDpi(new Size(300, 300));
103
104        $rectangle = new Rectangle(new Point(0, 0), $size);
105        $image->fillRectangle($backgroundColor, $rectangle);
106        $image->drawText($text, $fontSize, $rectangle, $foregroundColor, $textSetting);
107
108        $htmlSource = $image->saveHtmlSource(ImageSetting::png());
109        $image->dispose();
110
111        $dom = new HtmlDocument();
112        $img = $dom->addTagElement('img');
113        $img->setAttribute('src', $htmlSource);
114
115        $textHash = Cryptography::generateHashString(self::HASH_ALGORITHM, new Binary($text));
116        $img->setAttribute('data-hash', $textHash);
117        if (!Text::isNullOrWhiteSpace($className)) {
118            $img->setAttribute('class', $className);
119        }
120
121        if (!Text::isNullOrWhiteSpace($alt)) {
122            $img->setAttribute('alt', $alt);
123        }
124
125        return $dom->build();
126    }
127
128    protected function functionBodyImpl(): string
129    {
130        try {
131            return $this->functionBodyCore();
132        } catch (Throwable $ex) {
133            Throws::reThrow(TemplateException::class, $ex);
134        }
135    }
136
137    #endregion
138}