Completed
Push — master ( 3d03c6...f25c62 )
by Mikael
02:52
created

TShortcode::shortCodeAsciinema()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 28
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 28
ccs 0
cts 20
cp 0
rs 8.5806
cc 4
eloc 18
nc 8
nop 1
crap 20
1
<?php
2
3
namespace Mos\TextFilter;
4
5
/**
6
 * Shortcode to format when working with text.
7
 *
8
 */
9
trait TShortcode
10
{
11
    /**
12
     * Shortcode to quicker format text as HTML.
13
     *
14
     * @param string $text text to be converted.
15
     *
16
     * @return string the formatted text.
17
     */
18 2
    public function shortCode($text)
19
    {
20
        /* Needs PHP 7
21
        $patternsAndCallbacks = [
22
            "/\[(FIGURE)[\s+](.+)\]/" => function ($match) {
23
                return self::ShortCodeFigure($matches[2]);
24
            },
25
            "/(```([\w]*))\n([^`]*)```[\n]{1}/s" => function ($match) {
26
                return $this->syntaxHighlightGeSHi($matches[3], $matches[2]);
27
            },
28
        ];
29
30
        return preg_replace_callback_array($patternsAndCallbacks, $text);
31
        */
32
33
        $patterns = [
34 2
            "/\[(FIGURE)[\s+](.+)\]/",
35
            //'/\[(YOUTUBE) src=(.+) width=(.+) caption=(.+)\]/',
36 2
            "/\[(YOUTUBE)[\s+](.+)\]/",
37 2
            "/\[(ASCIINEMA)[\s+](.+)\]/",
38 2
            "/(```)([\w]*)\n([^`]*)```[\n]{1}/s",
39 2
            '/\[(INFO)\]/',
40 2
            '/\[(\/INFO)\]/',
41 2
        ];
42
43 2
        return preg_replace_callback(
44 2
            $patterns,
45 2
            function ($matches) {
46 2
                switch ($matches[1]) {
47 2
                    case "FIGURE":
48 1
                        return self::shortCodeFigure($matches[2]);
49
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
50
51 1
                    case "YOUTUBE":
52
                        return self::shortCodeYoutube($matches[2]);
53
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
54
55 1
                    case "ASCIINEMA":
56
                        return self::shortCodeAsciinema($matches[2]);
57
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
58
59 1
                    case "```":
60 1
                        return $this->syntaxHighlightGeSHi($matches[3], $matches[2]);
0 ignored issues
show
Bug introduced by
It seems like syntaxHighlightGeSHi() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
61
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
62
63
                    case 'INFO':
64
                        return "<div class='info' markdown=1>";
65
                        break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
66
67
                    case '/INFO':
68
                        return "</div>";
69
                        break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
70
71
                    default:
72
                        return "{$matches[1]} is unknown shortcode.";
73
                }
74 2
            },
75
            $text
76 2
        );
77
    }
78
79
80
81
    /**
82
     * Init shortcode handling by preparing the option list to an array,
83
     * for those using arguments.
84
     *
85
     * @param string $options for the shortcode.
86
     *
87
     * @return array with all the options.
88
     */
89 1
    public static function shortCodeInit($options)
90
    {
91 1
        preg_match_all('/[a-zA-Z0-9]+="[^"]+"|\S+/', $options, $matches);
92
93 1
        $res = array();
94 1
        foreach ($matches[0] as $match) {
95 1
            $pos = strpos($match, '=');
96 1
            if ($pos === false) {
97
                $res[$match] = true;
98
            } else {
99 1
                $key = substr($match, 0, $pos);
100 1
                $val = trim(substr($match, $pos+1), '"');
101 1
                $res[$key] = $val;
102
            }
103 1
        }
104
105 1
        return $res;
106
    }
107
108
109
110
    /**
111
     * Shortcode for [YOUTUBE].
112
     *
113
     * Usage example: [YOUTUBE src=id-for-the-tube width=630 caption=""]
114
     *
115
     * @param string $options for the shortcode.
116
     *
117
     * @return array with all the options.
118
     */
119
    public static function shortCodeYoutube($options)
120
    {
121
        $options= array_merge(
122
            [
123
                "src" => null,
124
                "width" => null,
125
                "caption" => null,
126
                "ratio" => 16/9
127
            ],
128
            self::ShortCodeInit($options)
129
        );
130
        extract($options, EXTR_SKIP);
131
132
        $caption = t("Figure: !CAPTION", ["!CAPTION" => $caption]);
133
        $height = ceil($width / $ratio);
134
135
        // @codingStandardsIgnoreStart
136
        $html = <<<EOD
137
<figure>
138
<iframe width="$width" height="$height" src="http://www.youtube.com/embed/$src" frameborder="0" allowfullscreen></iframe>
139
<figcaption markdown=1>{$caption}</figcaption>
140
</figure>
141
EOD;
142
        // @codingStandardsIgnoreEnd
143
144
        return $html;
145
    }
146
147
148
149
    /**
150
     * Shortcode for <figure>.
151
     *
152
     * Usage example: [FIGURE src="img/home/me.jpg" caption="Me" alt="Bild på mig" nolink="nolink"]
153
     *
154
     * @param string $options for the shortcode.
155
     *
156
     * @return array with all the options.
157
     */
158 1
    public static function shortCodeFigure($options)
159
    {
160
        // Merge incoming options with default and expose as variables
161 1
        $options= array_merge(
162
            [
163 1
                "id"    => null,
164 1
                "class" => null,
165 1
                "src"   => null,
166 1
                "title" => null,
167 1
                "alt"   => null,
168 1
                "caption" => null,
169 1
                "href"  => null,
170 1
                "nolink" => false,
171 1
            ],
172 1
            self::ShortCodeInit($options)
173 1
        );
174 1
        extract($options, EXTR_SKIP);
175
176 1
        $id = $id ? " id=\"$id\"" : null;
177 1
        $class = $class ? " class=\"figure $class\"" : " class=\"figure\"";
178 1
        $title = $title ? " title=\"$title\"" : null;
179
180 1
        if (!$alt && $caption) {
181 1
            $alt = $caption;
182 1
        }
183
184 1
        if (!$href) {
185 1
            $pos = strpos($src, "?");
186 1
            $href = $pos ? substr($src, 0, $pos) : $src;
187 1
        }
188
189 1
        $start = null;
190 1
        $end = null;
191 1
        if (!$nolink) {
192 1
            $start = "<a href=\"{$href}\">";
193 1
            $end = "</a>";
194 1
        }
195
196
        $html = <<<EOD
197 1
<figure{$id}{$class}>
198 1
{$start}<img src="{$src}" alt="{$alt}"{$title}/>{$end}
199 1
<figcaption markdown=1>{$caption}</figcaption>
200 1
</figure>
201 1
EOD;
202
203 1
        return $html;
204
    }
205
206
207
208
    /**
209
     * Shortcode for [asciinema].
210
     *
211
     * @param string $code the code to process.
0 ignored issues
show
Bug introduced by
There is no parameter named $code. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
212
     * @param string $options for the shortcode.
213
     * @return array with all the options.
214
     */
215
    public static function shortCodeAsciinema($options)
216
    {
217
        // Merge incoming options with default and expose as variables
218
        $options= array_merge(
219
            [
220
                "id" => null,
221
                "class" => null,
222
                "src" => null,
223
                "title" => null,
224
                "caption" => null,
225
            ],
226
            self::ShortCodeInit($options)
227
        );
228
        extract($options, EXTR_SKIP);
229
230
        $id = $id ? " id=\"$id\"" : null;
231
        $class = $class ? " class=\"figure asciinema $class\"" : " class=\"figure asciinema\"";
232
        $title = $title ? " title=\"$title\"" : null;
233
234
        $html = <<<EOD
235
<figure{$id}{$class}$title>
236
<script type="text/javascript" src="https://asciinema.org/a/{$src}.js" id="asciicast-{$src}" async></script>
237
<figcaption markdown=1>{$caption}</figcaption>
238
</figure>
239
EOD;
240
241
        return $html;
242
    }
243
244
245
246
    /**
247
     * Shortcode for including a SVG-image inside a <figure>.
248
     *
249
     * @param string $code the code to process.
250
     * @param string $options for the shortcode.
251
     * @return array with all the options.
252
     */
253
/*    public static function ShortCodeSVGFigure($options) {
254
        // Merge incoming options with default and expose as variables
255
        $options= array_merge(
256
            [
257
                "id"    => null,
258
                "class" => null,
259
                "src"   => null,
260
                "title" => null,
261
                "alt"   => null,
262
                "caption" => null,
263
                "href"  => null,
264
                "nolink" => false,
265
                //'path' => null,
266
            ],
267
            self::ShortCodeInit($options)
268
        );
269
        extract($options, EXTR_SKIP);
270
271
        $id = $id ? " id=\"$id\"" : null;
272
        $class = $class ? " class=\"figure $class\"" : " class=\"figure\"";
273
        $title = $title ? " title=\"$title\"" : null;
274
275
        if (!$alt && $caption) {
276
            $alt = $caption;
277
        }
278
279
        if (!$href) {
280
            $pos = strpos($src, "?");
281
            $href = $pos ? substr($src, 0, $pos) : $src;
282
        }
283
284
        $start = null;
285
        $end = null;
286
        if (!$nolink) {
287
            $start = "<a href=\"{$href}\">";
288
            $end = "</a>";
289
        }
290
291
        // Import the file containing the svg-image
292
        /*
293
        $svg = null;
294
295
        if($path[0] != '/') {
296
        $path = self::$dir . '/' . $path;
297
        }
298
299
        if(is_file($path)) {
300
        $svg = file_get_contents($path);
301
        }
302
        else {
303
        $svg = "No such file: $path";
304
        }
305
        $html = <<<EOD
306
        <figure{$id}{$class}>
307
        {$svg}
308
        <figcaption markdown=1>{$caption}</figcaption>
309
        </figure>
310
        EOD;*/
311
/*
312
        $html = <<<EOD
313
<figure{$id}{$class}>
314
{$start}<img src="{$src}" alt="{$alt}"{$title}/>{$end}
315
<figcaption markdown=1>{$caption}</figcaption>
316
</figure>
317
EOD;
318
319
        return $html;*/
320
/*    }
321
*/
322
323
324
325
/**
326
 * Shorttags to to quicker format text as HTML.
327
 *
328
 * @param string text text to be converted.
329
 * @return string the formatted text.
330
 */
331
/*public static function ShortTags($text) {
332
  $callback = function($matches) {
333
    switch($matches[1]) {
334
      case 'IMG':
335
        $caption = t('Image: ');
336
        $pos = strpos($matches[2], '?');
337
        $href = $pos ? substr($matches[2], 0, $pos) : $matches[2];
338
        $src = htmlspecialchars($matches[2]);
339
        return <<<EOD
340
<figure>
341
<a href='{$href}'><img src='{$src}' alt='{$matches[3]}' /></a>
342
<figcaption markdown=1>{$caption}{$matches[3]}</figcaption>
343
</figure>
344
EOD;
345
346
      case 'IMG2':
347
        $caption = null; //t('Image: ');
348
        $pos = strpos($matches[2], '?');
349
        $href = $pos ? substr($matches[2], 0, $pos) : $matches[2];
350
        $src = htmlspecialchars($matches[2]);
351
        return <<<EOD
352
<figure class="{$matches[4]}">
353
<a href='{$href}'><img src='{$src}' alt='{$matches[3]}' /></a>
354
<figcaption markdown=1>{$caption}{$matches[3]}</figcaption>
355
</figure>
356
EOD;
357
      case 'BOOK':
358
        $isbn = $matches[2];
359
        $stores = array(
360
          'BTH' => "http://bth.summon.serialssolutions.com/?#!/search?ho=t&amp;q={$isbn}",
361
          'Libris' => "http://libris.kb.se/hitlist?q={$isbn}",
362
          'Google Books' => "http://books.google.com/books?q={$isbn}",
363
          'Bokus' => "http://www.bokus.com/bok/{$isbn}",
364
          'Adlibris' => "http://www.adlibris.com/se/product.aspx?isbn={$isbn}",
365
          'Amazon' => "http://www.amazon.com/s/ref=nb_ss?url=field-keywords={$isbn}",
366
          'Barnes&Noble' => "http://search.barnesandnoble.com/booksearch/ISBNInquiry.asp?r=1&IF=N&EAN={$isbn}",
367
        );
368
        $html = null;
369
        foreach($stores as $key => $val) {
370
          $html .= "<a href='$val'>$key</a> &bull; ";
371
        }
372
        return substr($html, 0, -8);
373
      break;
374
375
      case 'YOUTUBE':
376
        $caption = t('Figure: ');
377
        $height = ceil($matches[3] / (16/9));
378
        return <<<EOD
379
<figure>
380
<iframe width='{$matches[3]}' height='{$height}' src="http://www.youtube.com/embed/{$matches[2]}" frameborder="0"
381
allowfullscreen></iframe>
382
<figcaption>{$caption}{$matches[4]}</figcaption>
383
</figure>
384
EOD;
385
      break;
386
      
387
      case 'syntax=': return CTextFilter::SyntaxHighlightGeSHi($matches[3], $matches[2]); break;
388
      case '```': return CTextFilter::SyntaxHighlightGeSHi($matches[3], $matches[2]); break;
389
      //case 'syntax=': return "<pre>" . highlight_string($matches[3], true) . "</pre>"; break;
390
      //case 'INCL':  include($matches[2]); break;
391
      case 'INFO':  return "<div class='info' markdown=1>"; break;
392
      case '/INFO': return "</div>"; break;
393
      case 'BASEURL': return CLydia::Instance()->request->base_url; break;
394
      case 'FIGURE': return CTextFilter::ShortCodeFigure($matches[2]); break;
395
      case 'FIGURE-SVG': return CTextFilter::ShortCodeSVGFigure($matches[2]); break;
396
      case 'ASCIINEMA': return CTextFilter::ShortCodeAsciinema($matches[2]); break;
397
      default: return "{$matches[1]} IS UNKNOWN SHORTTAG."; break;
398
    }
399
  };
400
  $patterns = array(
401
    '#\[(BASEURL)\]#',
402
    //'/\[(AUTHOR) name=(.+) email=(.+) url=(.+)\]/',
403
    '/\[(FIGURE)[\s+](.+)\]/',
404
    '/\[(FIGURE-SVG)[\s+](.+)\]/',
405
    '/\[(ASCIINEMA)[\s+](.+)\]/',
406
    '/\[(IMG) src=(.+) alt=(.+)\]/',
407
    '/\[(IMG2) src=(.+) alt="(.+)" class="(.+)"\]/',
408
    '/\[(BOOK) isbn=(.+)\]/',
409
    '/\[(YOUTUBE) src=(.+) width=(.+) caption=(.+)\]/',
410
    '/~~~(syntax=)(php|html|html5|css|sql|javascript|bash)\n([^~]+)\n~~~/s',
411
    '/(```)(php|html|html5|css|sql|javascript|bash|text|txt|python)\n([^`]+)\n```/s',
412
    //'/\[(INCL)/s*([^\]+)/',
413
    '#\[(INFO)\]#', '#\[(/INFO)\]#',
414
  );
415
416
  $ret = preg_replace_callback($patterns, $callback, $text);
417
  return $ret;
418
}
419
*/
420
}
421