Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
72.22% covered (success)
72.22%
13 / 18
CRAP
79.52% covered (success)
79.52%
66 / 83
AbstractTemplate
0.00% covered (danger)
0.00%
0 / 1
72.22% covered (success)
72.22%
13 / 18
40.80
79.52% covered (success)
79.52%
66 / 83
 __construct
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
4 / 4
 __get
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 3
 getLinePosition
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
4 / 4
 getDraw
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 truncateText
0.00% covered (danger)
0.00%
0 / 1
2.03
80.00% covered (success)
80.00%
4 / 5
 getTemplateDetails
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 initFontColor
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
4 / 4
 setFontColor
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 setFont
0.00% covered (danger)
0.00%
0 / 1
3.00
93.75% covered (success)
93.75%
15 / 16
 createDraw
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
5 / 5
 previsousLineSum
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
4 / 4
 fontSize
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 fontWeight
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 kerning
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 spacing
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 fontColor
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
4 / 4
 getValueOrDefault
0.00% covered (danger)
0.00%
0 / 1
4.05
85.71% covered (success)
85.71%
6 / 7
 startPosition
0.00% covered (danger)
0.00%
0 / 1
14.86
26.67% covered (danger)
26.67%
4 / 15
1<?php
2
3namespace Qmp\Laravel\Adserving\Services\Drawer\Templates;
4
5use Illuminate\Support\Collection;
6use Illuminate\Support\Facades\Log;
7use Illuminate\Support\Facades\Storage;
8use Qmp\Laravel\Adserving\Services\Drawer\DrawerConfig;
9
10abstract class AbstractTemplate
11{
12    const FONT_DISK = 'fonts';
13    const FONT_REGULAR = '-Regular';
14    const FONT_BOLD = '-Bold';
15    const FONT = [
16        'name' => 'OpenSans',
17        'ext' => '.ttf'
18    ];
19    const FONT_RATIO = 1.6;
20
21    protected $padding = 10;
22    protected $canvasHeight = 100;
23    protected $canvasWidth = 390;
24    protected $lineColor = [];
25    protected $defaultFontColor = [
26        'color-1' => '#000000',
27        'color-2' => '#0075c5'
28    ];
29    protected $defaultFontSize = 18;
30    protected $textAlign = 'top-left';
31    protected $spacing = [];
32    protected $defaultSpacing = 10;
33    protected $fontWeight = [];
34    protected $defaultFontWeight = 400;
35    protected $kerning = [];
36    protected $defaultKerning = 0;
37    protected $fontSize = [];
38    protected $draw;
39    protected $config;
40
41    public function __construct(DrawerConfig $config)
42    {
43        $this->config = $config;
44
45        $this->initFontColor();
46        $this->createDraw();
47    }
48
49    public function __get($prop)
50    {
51        if (property_exists($this, $prop)) {
52            return $this->$prop;
53        }
54        return null;
55    }
56
57    public function getLinePosition($nth)
58    {
59        [$x, $y] = $this->startPosition();
60
61        return collect([
62            'x' => $x,
63            'y' => $this->previsousLineSum($nth)
64        ]);
65    }
66
67    public function getDraw($nth): \ImagickDraw
68    {
69        $this->setFont($nth);
70        $this->setFontColor($nth);
71        return $this->draw;
72    }
73
74    public function truncateText($text, $nth)
75    {
76        $availableWidth = $this->canvasWidth - ($this->padding * 2);
77        $maxTextChars = intval($availableWidth / (($this->fontSize($nth) + $this->kerning($nth)) / self::FONT_RATIO)) - 3.5;
78
79        if (strlen($text) > $maxTextChars) {
80            return substr($text, 0, $maxTextChars) . '...';
81        } else {
82            return $text;
83        }
84    }
85
86    public function getTemplateDetails()
87    {
88        return [
89            'height' => $this->canvasHeight,
90            'width' => $this->canvasWidth,
91            'fontColor' => $this->defaultFontColor,
92        ];
93    }
94
95    protected function initFontColor()
96    {
97        $this->defaultFontColor = collect($this->defaultFontColor);
98
99        if ($this->config->get('fontColor')) {
100            $this->defaultFontColor = $this->defaultFontColor->merge($this->config->get('fontColor'));
101        }
102    }
103
104    protected function setFontColor($nth)
105    {
106        $this->draw->setFillColor(new \ImagickPixel($this->fontColor($nth)));
107    }
108
109    protected function setFont($nth)
110    {
111        $tempFont = $this->config->get('font') ?? self::FONT;
112        $fontName = $tempFont['name'];
113        $ext = $tempFont['ext'];
114
115        $font =  Storage::disk(SELF::FONT_DISK)->path('') . $fontName;
116        $fontColor = $this->fontColor($nth);
117
118        $this->draw->setFontSize($this->fontSize($nth));
119        $this->draw->setTextKerning($this->kerning($nth));
120
121        if ($this->fontWeight($nth) === 800) {
122            if (file_exists($font . self::FONT_BOLD . $ext)) {
123                $this->draw->setFont($font . self::FONT_BOLD . $ext);
124            } else {
125
126                $this->draw->setStrokeColor($fontColor);
127                $this->draw->setStrokeWidth(1);
128            }
129        } else {
130            $this->draw->setFont($font . self::FONT_REGULAR . $ext);
131            $this->draw->setStrokeColor($fontColor . '00');
132            $this->draw->setStrokeWidth(0);
133        }
134    }
135
136    protected function createDraw()
137    {
138        $this->draw = new \ImagickDraw();
139        $this->draw->setStrokeAntialias(true);
140        $this->draw->setTextAntialias(true);
141        $this->draw->setGravity(\Imagick::GRAVITY_NORTHWEST);
142    }
143
144    protected function previsousLineSum($nth)
145    {
146        $previousLinesum = $this->padding;
147        for ($i = 0; $i < $nth; $i++) {
148            $previousLinesum += $this->fontSize($nth - 1) + $this->spacing($nth);
149        }
150        return $previousLinesum;
151    }
152
153    protected function fontSize($nth)
154    {
155        return $this->getValueOrDefault('fontSize', $nth);
156    }
157
158    protected function fontWeight($nth)
159    {
160        return $this->getValueOrDefault('fontWeight', $nth);
161    }
162
163    protected function kerning($nth)
164    {
165        return $this->getValueOrDefault('kerning', $nth);
166    }
167
168    protected function spacing($nth)
169    {
170        return $this->getValueOrDefault('spacing', $nth);
171    }
172
173    protected function fontColor($nth)
174    {
175        $color =  $this->getValueOrDefault('fontColor', $nth);
176        return is_a($color, Collection::class)
177            ? $this->defaultFontColor->get('color-1')
178            : $this->defaultFontColor->get($color);
179    }
180
181    protected function getValueOrDefault($prop, $nth)
182    {
183        if ($nth >= 0) {
184            $nth += 1;
185            $default = "default" . ucfirst($prop);
186
187            if (is_array($this->$prop) && array_key_exists('line-' . $nth, $this->$prop)) {
188                return $this->$prop['line-' . $nth];
189            }
190
191            return $this->$default;
192        }
193        return 0;
194    }
195
196    protected function startPosition()
197    {
198        switch ($this->textAlign) {
199            case 'top-left';
200                return [
201                    0 + $this->padding,
202                    0 + $this->padding
203                ];
204                break;
205            case 'top-right';
206                return [
207                    $this->canvasWidth - $this->padding,
208                    0 + $this->padding
209                ];
210                break;
211            case 'bottom-left';
212                return [
213                    0 + $this->padding,
214                    $this->canvasHeight - $this->padding
215                ];
216                break;
217            case 'bottom-right';
218                return [
219                    $this->canvasWidth - $this->padding,
220                    $this->canvasHeight - $this->padding
221                ];
222                break;
223        }
224    }
225}