Passed
Push — feature/toc ( f0827c...972902 )
by Arnaud
03:49
created

Parsedown   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 124
Duplicated Lines 0 %

Test Coverage

Coverage 96.72%

Importance

Changes 8
Bugs 1 Features 0
Metric Value
eloc 61
c 8
b 1
f 0
dl 0
loc 124
ccs 59
cts 61
cp 0.9672
rs 10
wmc 18

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A removeQuery() 0 3 1
C inlineImage() 0 102 16
1
<?php
2
/**
3
 * This file is part of the Cecil/Cecil package.
4
 *
5
 * Copyright (c) Arnaud Ligny <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Cecil\Converter;
12
13
use Cecil\Assets\Image;
14
use Cecil\Builder;
15
use Cecil\Util;
16
17
class Parsedown extends \ParsedownToC
18
{
19
    /** @var Builder */
20
    private $builder;
21
22
    /**
23
     * {@inheritdoc}
24
     */
25
    public function __construct(Builder $builder)
26
    {
27 1
        $this->builder = $builder;
28
        parent::__construct(['selectors' => $this->builder->getConfig()->get('body.toc')]);
29 1
    }
30 1
31 1
    /**
32
     * {@inheritdoc}
33
     */
34
    protected function inlineImage($excerpt)
35
    {
36
        $image = parent::inlineImage($excerpt);
37
38 1
        if (!isset($image)) {
39
            return null;
40 1
        }
41 1
42
        // fetch image path
43 1
        $path = Util::joinFile(
44 1
            $this->builder->getConfig()->getStaticTargetPath(),
45 1
            ltrim($this->removeQuery($image['element']['attributes']['src']))
46
        );
47
        if (Util\Url::isUrl($image['element']['attributes']['src'])) {
48 1
            $path = $this->removeQuery($image['element']['attributes']['src']);
49
        }
50 1
        if (!is_file($path) && !Util\Url::isRemoteFileExists($path)) {
51 1
            return $image;
52 1
        }
53
54 1
        // fetch image properties
55 1
        $size = getimagesize($path);
56 1
        $width = $size[0];
57 1
        $type = $size[2];
58 1
59
        // sets default attributes
60
        $image['element']['attributes']['width'] = $width;
61
        if ($type !== null) {
62 1
            $image['element']['attributes']['loading'] = 'lazy';
63
        }
64
65
        // captures query string.
66
        // ie: "?resize=300&responsive"
67
        $query = parse_url($image['element']['attributes']['src'], PHP_URL_QUERY);
68
        if ($query === null) {
69 1
            return $image;
70
        }
71 1
        parse_str($query, $result);
72
        // cleans URL
73 1
        $image['element']['attributes']['src'] = $this->removeQuery($image['element']['attributes']['src']);
74
75
        /**
76
         * Should be responsive?
77
         */
78 1
        $responsive = false;
79 1
        if (array_key_exists('responsive', $result) && !Util\Url::isUrl($image['element']['attributes']['src'])) {
80 1
            $responsive = true;
81
            // process
82 1
            $steps = 5;
83 1
            $wMin = 320;
84
            $wMax = 2560;
85 1
            if ($width < $wMax) {
86 1
                $wMax = $width;
87
            }
88
            $srcset = '';
89
            for ($i = 1; $i <= $steps; $i++) {
90 1
                $w = (int) ceil($wMin + ($wMax - $wMin) / $steps * $i);
91 1
                $img = (new Image($this->builder))
92 1
                    ->load($image['element']['attributes']['src'])
93
                    ->resize($w);
94
                $srcset .= sprintf('%s %sw', $img, $w);
95 1
                if ($i < $steps) {
96 1
                    $srcset .= ', ';
97 1
                }
98
            }
99
            // ie: srcset="/img-480.jpg 480w, img-800.jpg 800w"
100
            $image['element']['attributes']['srcset'] = $srcset;
101
        }
102 1
103 1
        /**
104 1
         * Should be resized?
105
         */
106 1
        if (array_key_exists('resize', $result)) {
107
            $size = (int) $result['resize'];
108 1
            $width = $size;
109
110
            $imageResized = (new Image($this->builder))
111
                ->load($image['element']['attributes']['src'])
112
                ->resize($size);
113 1
114 1
            $image['element']['attributes']['src'] = $imageResized;
115 1
            $image['element']['attributes']['width'] = $width;
116
117 1
            if (Util\Url::isUrl($image['element']['attributes']['src'])) {
118 1
                return $image;
119 1
            }
120 1
        }
121 1
122
        // if responsive: set 'sizes' attribute
123 1
        if ($responsive) {
124 1
            // sizes="(max-width: 2800px) 100vw, 2800px"
125 1
            $image['element']['attributes']['sizes'] = sprintf('(max-width: %spx) 100vw, %spx', $width, $width);
126 1
        }
127 1
128 1
        // set 'class' attribute
129 1
        if (array_key_exists('class', $result)) {
130 1
            $class = $result['class'];
131 1
            $class = strtr($class, ',', ' ');
132
            $image['element']['attributes']['class'] = $class;
133
        }
134
135 1
        return $image;
136
    }
137
138
    private function removeQuery(string $path): string
139
    {
140
        return strtok($path, '?');
141 1
    }
142
}
143