Passed
Push — analysis-lKdyyr ( a18489 )
by Arnaud
11:37 queued 07:05
created

Parsedown::blockHeader()   A

Complexity

Conditions 5
Paths 9

Size

Total Lines 38
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 5
eloc 15
c 2
b 1
f 0
nc 9
nop 1
dl 0
loc 38
rs 9.4555
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
        parent::__construct(['selectors' => ['h2', 'h3']]);
28
        $this->builder = $builder;
29
    }
30
31
    // hack ParsedownToc
32
    protected function blockHeader($Line)
33
    {
34
        $text = '';
35
36
        // Use parent blockHeader method to process the $Line to $Block
37
        $Block = \ParsedownExtra::blockHeader($Line);
0 ignored issues
show
Bug Best Practice introduced by
The method ParsedownExtra::blockHeader() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

37
        /** @scrutinizer ignore-call */ 
38
        $Block = \ParsedownExtra::blockHeader($Line);
Loading history...
38
39
        if (!empty($Block)) {
40
            // Get the text of the heading
41
            //if (isset($Block['element']['handler']['argument'])) {
42
            //    $text = $Block['element']['handler']['argument'];
43
            //}
44
            if (isset($Block['element']['text'])) {
45
                $text = $Block['element']['text'];
46
            }
47
48
            // Get the heading level. Levels are h1, h2, ..., h6
49
            $level = $Block['element']['name'];
50
51
            // Get the anchor of the heading to link from the ToC list
52
            $id = isset($Block['element']['attributes']['id']) ?
53
                $Block['element']['attributes']['id'] : $this->createAnchorID($text);
54
55
            // Set attributes to head tags
56
            $Block['element']['attributes']['id'] = $id;
57
58
            // Check if level are defined as a selector
59
            if (in_array($level, $this->options['selectors'])) {
60
61
                // Add/stores the heading element info to the ToC list
62
                $this->setContentsList([
63
                    'text'  => $text,
64
                    'id'    => $id,
65
                    'level' => $level,
66
                ]);
67
            }
68
69
            return $Block;
70
        }
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76
    protected function inlineImage($excerpt)
77
    {
78
        $image = parent::inlineImage($excerpt);
79
80
        if (!isset($image)) {
81
            return null;
82
        }
83
84
        // fetch image path
85
        $path = Util::joinFile(
86
            $this->builder->getConfig()->getStaticTargetPath(),
87
            ltrim($this->removeQuery($image['element']['attributes']['src']))
88
        );
89
        if (Util\Url::isUrl($image['element']['attributes']['src'])) {
90
            $path = $this->removeQuery($image['element']['attributes']['src']);
91
        }
92
        if (!is_file($path) && !Util\Url::isRemoteFileExists($path)) {
93
            return $image;
94
        }
95
96
        // fetch image properties
97
        $size = getimagesize($path);
98
        $width = $size[0];
99
        $type = $size[2];
100
101
        // sets default attributes
102
        $image['element']['attributes']['width'] = $width;
103
        if ($type !== null) {
104
            $image['element']['attributes']['loading'] = 'lazy';
105
        }
106
107
        // captures query string.
108
        // ie: "?resize=300&responsive"
109
        $query = parse_url($image['element']['attributes']['src'], PHP_URL_QUERY);
110
        if ($query === null) {
111
            return $image;
112
        }
113
        parse_str($query, $result);
114
        // cleans URL
115
        $image['element']['attributes']['src'] = $this->removeQuery($image['element']['attributes']['src']);
116
117
        /**
118
         * Should be responsive?
119
         */
120
        $responsive = false;
121
        if (array_key_exists('responsive', $result) && !Util\Url::isUrl($image['element']['attributes']['src'])) {
122
            $responsive = true;
123
            // process
124
            $steps = 5;
125
            $wMin = 320;
126
            $wMax = 2560;
127
            if ($width < $wMax) {
128
                $wMax = $width;
129
            }
130
            $srcset = '';
131
            for ($i = 1; $i <= $steps; $i++) {
132
                $w = (int) ceil($wMin + ($wMax - $wMin) / $steps * $i);
133
                $img = (new Image($this->builder))
134
                    ->load($image['element']['attributes']['src'])
135
                    ->resize($w);
136
                $srcset .= sprintf('%s %sw', $img, $w);
137
                if ($i < $steps) {
138
                    $srcset .= ', ';
139
                }
140
            }
141
            // ie: srcset="/img-480.jpg 480w, img-800.jpg 800w"
142
            $image['element']['attributes']['srcset'] = $srcset;
143
        }
144
145
        /**
146
         * Should be resized?
147
         */
148
        if (array_key_exists('resize', $result)) {
149
            $size = (int) $result['resize'];
150
            $width = $size;
151
152
            $imageResized = (new Image($this->builder))
153
                ->load($image['element']['attributes']['src'])
154
                ->resize($size);
155
156
            $image['element']['attributes']['src'] = $imageResized;
157
            $image['element']['attributes']['width'] = $width;
158
159
            if (Util\Url::isUrl($image['element']['attributes']['src'])) {
160
                return $image;
161
            }
162
        }
163
164
        // if responsive: set 'sizes' attribute
165
        if ($responsive) {
166
            // sizes="(max-width: 2800px) 100vw, 2800px"
167
            $image['element']['attributes']['sizes'] = sprintf('(max-width: %spx) 100vw, %spx', $width, $width);
168
        }
169
170
        // set 'class' attribute
171
        if (array_key_exists('class', $result)) {
172
            $class = $result['class'];
173
            $class = strtr($class, ',', ' ');
174
            $image['element']['attributes']['class'] = $class;
175
        }
176
177
        return $image;
178
    }
179
180
    private function removeQuery(string $path): string
181
    {
182
        return strtok($path, '?');
183
    }
184
}
185