Passed
Push — master ( 289f9d...bae7fb )
by Sebastian
04:42
created

StringBuilder::tex()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 8
c 1
b 0
f 0
dl 0
loc 14
rs 10
cc 2
nc 2
nop 3
1
<?php
2
/**
3
 * File containing the {@link StringBuilder} class.
4
 *
5
 * @package Application Utils
6
 * @subpackage StringBuilder
7
 * @see StringBuilder
8
 */
9
10
declare(strict_types=1);
11
12
namespace AppUtils;
13
14
use DateTime;
15
use AppLocalize;
16
17
/**
18
 * Utility class used to easily concatenate strings
19
 * with a chainable interface. 
20
 * 
21
 * Each bit of text that is added is automatically 
22
 * separated by spaces, making it easy to write
23
 * texts without handling this separately.
24
 * 
25
 * Specialized methods help in quickly formatting 
26
 * text, or adding common HTML-based contents.
27
 *
28
 * @package Application Utils
29
 * @subpackage StringBuilder
30
 * @author Sebastian Mordziol <[email protected]>
31
 *
32
 * @see StringBuilder
33
 */
34
class StringBuilder implements StringBuilder_Interface
35
{
36
   /**
37
    * @var string
38
    */
39
    protected $separator = ' ';
40
41
   /**
42
    * @var string[]
43
    */
44
    protected $strings = array();
45
46
   /**
47
    * @var string
48
    */
49
    protected $mode = 'html';
50
51
   /**
52
    * @var string
53
    */
54
    protected $noSpace = '§!§';
55
    
56
    public function __construct()
57
    {
58
        
59
    }
60
    
61
   /**
62
    * Adds a subject as a string. Is ignored if empty.
63
    * 
64
    * @param string|number|StringBuilder_Interface $string
65
    * @return $this
66
    */
67
    public function add($string) : StringBuilder
68
    {
69
        $string = strval($string);
70
        
71
        if(!empty($string)) 
72
        {
73
            $this->strings[] = $string;
74
        }
75
        
76
        return $this;
77
    }
78
    
79
   /**
80
    * Adds a string without appending an automatic space.
81
    * 
82
    * @param string|number|StringBuilder_Interface $string
83
    * @return $this
84
    */
85
    public function nospace($string) : StringBuilder
86
    {
87
        return $this->add($this->noSpace.strval($string));
88
    }
89
    
90
   /**
91
    * Adds raw HTML code. Does not add an automatic space.
92
    * 
93
    * @param string|number|StringBuilder_Interface $html
94
    * @return $this
95
    */
96
    public function html($html) : StringBuilder
97
    {
98
        return $this->nospace($html);
99
    }
100
    
101
   /**
102
    * Adds an unordered list with the specified items.
103
    * 
104
    * @param array<int,string|number|StringBuilder_Interface> $items
105
    * @return $this
106
    */
107
    public function ul(array $items) : StringBuilder
108
    {
109
        return $this->list('ul', $items);
110
    }
111
    
112
   /**
113
    * Adds an ordered list with the specified items.
114
    * 
115
    * @param array<int,string|number|StringBuilder_Interface> $items
116
    * @return $this
117
    */
118
    public function ol(array $items) : StringBuilder
119
    {
120
        return $this->list('ol', $items);
121
    }
122
    
123
   /**
124
    * Creates a list tag with the items list.
125
    * 
126
    * @param string $type The list type, `ol` or `ul`.
127
    * @param array<int,string|number|StringBuilder_Interface> $items
128
    * @return $this
129
    */
130
    protected function list(string $type, array $items) : StringBuilder
131
    {
132
        return $this->html(sprintf(
133
            '<%1$s><li>%2$s</li></%1$s>',
134
            $type,
135
            implode('</li><li>', $items)
136
        ));
137
    }
138
    
139
   /**
140
    * Add a translated string.
141
    * 
142
    * @param string $format The native string to translate.
143
    * @param array<int,mixed> $arguments The variables to inject into the translated string, if any.
144
    * @return $this
145
    */
146
    public function t(string $format, ...$arguments) : StringBuilder
147
    {
148
        if(!class_exists('\AppLocalize\Localization'))
149
        {
150
            array_unshift($arguments, $format);
151
            return $this->sf(...$arguments);
152
        }
153
        
154
        return $this->add(call_user_func(
155
            array(AppLocalize\Localization::getTranslator(), 'translate'),
156
            $format,
157
            $arguments
158
        ));
159
    }
160
161
    /**
162
     * Add a translated text with translation context information.
163
     *
164
     * @param string $format The native string to translate.
165
     * @param string $context Translation context hints, shown in the translation UI.
166
     * @param mixed ...$arguments
167
     * @return $this
168
     */
169
    public function tex(string $format, string $context, ...$arguments) : StringBuilder
170
    {
171
        unset($context); // Only used by the localization parser.
172
173
        if(!class_exists('\AppLocalize\Localization'))
174
        {
175
            array_unshift($arguments, $format);
176
            return $this->sf(...$arguments);
177
        }
178
179
        return $this->add(call_user_func(
180
            array(AppLocalize\Localization::getTranslator(), 'translate'),
181
            $format,
182
            $arguments
183
        ));
184
    }
185
186
    /**
187
     * Adds a "5 months ago" age since the specified date.
188
     *
189
     * @param DateTime $since
190
     * @return $this
191
     * @throws ConvertHelper_Exception
192
     */
193
    public function age(DateTime $since) : StringBuilder
194
    {
195
        return $this->add(ConvertHelper::duration2string($since));
196
    }
197
    
198
   /**
199
    * Adds HTML double quotes around the string.
200
    * 
201
    * @param string|number|StringBuilder_Interface $string
202
    * @return $this
203
    */
204
    public function quote($string)
205
    {
206
        return $this->sf('&quot;%s&quot;', strval($string));
207
    }
208
    
209
   /**
210
    * Adds a text that is meant as a reference to an UI element,
211
    * like a menu item, button, etc.
212
    * 
213
    * @param string|number|StringBuilder_Interface $string 
214
    * @return $this
215
    */
216
    public function reference($string) : StringBuilder
217
    {
218
        return $this->sf('"%s"', $string);
219
    }
220
221
   /**
222
    * Add a string using the `sprintf` method.
223
    * 
224
    * @param string $format The format string
225
    * @param string|number|StringBuilder_Interface ...$arguments The variables to inject
226
    * @return $this
227
    */
228
    public function sf(string $format, ...$arguments) : StringBuilder
229
    {
230
        array_unshift($arguments, $format);
231
        
232
        return $this->add(call_user_func_array('sprintf', $arguments));
233
    }
234
    
235
   /**
236
    * Adds a bold string.
237
    * 
238
    * @param string|number|StringBuilder_Interface $string
239
    * @return $this
240
    */
241
    public function bold($string) : StringBuilder
242
    {
243
        return $this->sf(
244
            '<b>%s</b>', 
245
            strval($string)
246
        );
247
    }
248
    
249
   /**
250
    * Adds an HTML `<br>` tag.
251
    *
252
    * Note: for adding a newline character instead,
253
    * use {@see StringBuilder::eol()}.
254
    * 
255
    * @return $this
256
    * @see StringBuilder::eol()
257
    */
258
    public function nl() : StringBuilder
259
    {
260
        return $this->html('<br>');
261
    }
262
263
    /**
264
     * Adds an EOL character, without space.
265
     *
266
     * @return $this
267
     * @see StringBuilder::nl()
268
     */
269
    public function eol() : StringBuilder
270
    {
271
        return $this->nospace(PHP_EOL);
272
    }
273
    
274
   /**
275
    * Adds the current time, in the format <code>H:i:s</code>.
276
    * 
277
    * @return $this
278
    */
279
    public function time() : StringBuilder
280
    {
281
        return $this->add(date('H:i:s'));
282
    }
283
    
284
   /**
285
    * Adds the "Note:" text.
286
    * 
287
    * @return $this
288
    */
289
    public function note() : StringBuilder
290
    {
291
        return $this->t('Note:');
292
    }
293
    
294
   /**
295
    * Like {@see StringBuilder::note()}, but as bold text.
296
    * 
297
    * @return $this
298
    */
299
    public function noteBold() : StringBuilder
300
    {
301
        return $this->bold(sb()->note());
302
    }
303
    
304
   /**
305
    * Adds the "Hint:" text.
306
    * 
307
    * @return $this
308
    * @see StringBuilder::hintBold()
309
    */
310
    public function hint() : StringBuilder
311
    {
312
        return $this->t('Hint:');
313
    }
314
315
    /**
316
     * Like {@see StringBuilder::hint()}, but as bold text.
317
     *
318
     * @return $this
319
     */
320
    public function hintBold() : StringBuilder
321
    {
322
        return $this->bold(sb()->hint());
323
    }
324
    
325
   /**
326
    * Adds two linebreaks.
327
    *
328
    * @param StringBuilder_Interface|string|NULL $content
329
    * @return $this
330
    */
331
    public function para($content=null) : StringBuilder
332
    {
333
        if($content !== null) {
334
            return $this->html('<p>')->nospace($content)->html('</p>');
335
        }
336
337
        return $this->nl()->nl();
338
    }
339
    
340
   /**
341
    * Adds an anchor HTML tag.
342
    * 
343
    * @param string $label
344
    * @param string $url
345
    * @param bool $newTab
346
    * @return $this
347
    */
348
    public function link(string $label, string $url, bool $newTab=false) : StringBuilder
349
    {
350
        $target = '';
351
        if($newTab) {
352
            $target = ' target="_blank"';
353
        }
354
       
355
        return $this->sf(
356
            '<a href="%s"%s>%s</a>',
357
            $url,
358
            $target,
359
            $label
360
        );
361
    }
362
    
363
   /**
364
    * Wraps the string in a `code` tag.
365
    * 
366
    * @param string|number|StringBuilder_Interface $string
367
    * @return $this
368
    */
369
    public function code($string) : StringBuilder
370
    {
371
        return $this->sf(
372
            '<code>%s</code>',
373
            strval($string)
374
        );
375
    }
376
    
377
   /**
378
    * Wraps the string in a `pre` tag.
379
    * 
380
    * @param string|number|StringBuilder_Interface $string
381
    * @return $this
382
    */
383
    public function pre($string) : StringBuilder
384
    {
385
        return $this->sf('<pre>%s</pre>', strval($string));
386
    }
387
    
388
   /**
389
    * Wraps the text in a `span` tag with the specified classes.
390
    * 
391
    * @param string|number|StringBuilder_Interface $string
392
    * @param string|string[] $classes
393
    * @return $this
394
    */
395
    public function spanned($string, $classes) : StringBuilder
396
    {
397
        if(!is_array($classes)) 
398
        {
399
            $classes = array(strval($classes));
400
        }
401
        
402
        return $this->sf(
403
            '<span class="%s">%s</span>',
404
            implode(' ', $classes),
405
            strval($string)
406
        );
407
    }
408
    
409
    public function render() : string
410
    {
411
        $result = implode($this->separator, $this->strings);
412
        
413
        return str_replace(array(' '.$this->noSpace, $this->noSpace), '', $result);
414
    }
415
    
416
    public function __toString()
417
    {
418
        return $this->render();
419
    }
420
    
421
    public function display() : void
422
    {
423
        echo $this->render();
424
    }
425
}
426