Issues (28)

src/Markdown/Markdown.php (1 issue)

Severity
1
<?php
2
3
namespace Wingsline\Blog\Markdown;
4
5
use Intervention\Image\ImageManager;
6
use Michelf\MarkdownExtra;
7
8
class Markdown extends MarkdownExtra
9
{
10
    /**
11
     * High Pixel density descriptor.
12
     */
13
    const HIGH_PIXEL_DENSITY = '2x';
14
15
    /**
16
     * Above this size we consider the image high ppi.
17
     */
18
    const MAX_POINT_PER_INCH = 96;
19
20
    /**
21
     * Add srcset for the locally stored image.
22
     *
23
     * @param string $url
24
     */
25
    public function addSrcSet($url): string
26
    {
27
        $result = ' srcset="'.$url;
28
29
        // for local images we expand to the full path
30
31
        if (is_file(public_path($url))) {
32
            $image_url = public_path($url);
33
        } else {
34
            $image_url = url($url);
35
        }
36
37
        $result .= $this->getImagePixelDensity($image_url);
38
        $result .= '"';
39
40
        return $result;
41
    }
42
43
    /**
44
     * Converts markdown to html.
45
     */
46
    public function convertToHtml(string $markdown): string
47
    {
48
        return static::defaultTransform($markdown);
49
    }
50
51
    /**
52
     * Static method to convert markdown to html.
53
     *
54
     * @return string
55
     */
56
    public static function convertWithParser(string $markdown)
57
    {
58
        $method = config('blog.markdown_parser.method');
59
60
        return app(config('blog.markdown_parser.class'))
61
            ->{$method}($markdown);
62
    }
63
64
    /**
65
     * Returns 2x if the image is high pixel density.
66
     *
67
     * @param string $image_url
68
     *
69
     * @return string
70
     */
71
    public function getImagePixelDensity($image_url)
72
    {
73
        // Currently we support only imagick
74
        if (! \extension_loaded('imagick')) {
75
            return '';
76
        }
77
78
        try {
79
            $manager = new ImageManager(['driver' => 'imagick']);
80
            $img = $manager->make($image_url)->getCore();
81
        } catch (\Exception $e) {
82
            return '';
83
        }
84
85
        $unit = $img->getImageUnits();
86
        $resolution = array_sum($img->getImageResolution());
87
88
        // Based on the units we determine if the image is high dpi. If no
89
        // resolution is set, we default to high dpi, since imagick cannot
90
        // reliably detect for example phone screenshot resolutions.
91
        $pixel_density = ' ';
92
93
        switch ($unit) {
94
            case \imagick::RESOLUTION_PIXELSPERINCH:
95
                $max_resolution = (static::MAX_POINT_PER_INCH * 2);
96
                $pixel_density .= $resolution > $max_resolution ? static::HIGH_PIXEL_DENSITY : '';
97
98
                break;
99
            case \imagick::RESOLUTION_PIXELSPERCENTIMETER:
100
                $max_resolution = (static::MAX_POINT_PER_INCH * 2) / 2.54;
101
                $pixel_density .= $resolution > $max_resolution ? static::HIGH_PIXEL_DENSITY : '';
102
103
                break;
104
            default:
105
                $pixel_density .= static::HIGH_PIXEL_DENSITY;
106
107
                break;
108
        }
109
110
        return rtrim($pixel_density);
111
    }
112
113
    /**
114
     * Callback for inline images.
115
     *
116
     * @param array $matches
117
     *
118
     * @return string
119
     */
120
    protected function _doImages_inline_callback($matches)
121
    {
122
        $whole_match = $matches[1];
0 ignored issues
show
The assignment to $whole_match is dead and can be removed.
Loading history...
123
        $alt_text = $matches[2];
124
        $url = '' == $matches[3] ? $matches[4] : $matches[3];
125
        $title = &$matches[7];
126
        $attr = $this->doExtraAttributes('img', $dummy = &$matches[8]);
127
128
        $alt_text = $this->encodeAttribute($alt_text);
129
        $url = $this->encodeURLAttribute($url);
130
        $result = "<img src=\"${url}\" alt=\"${alt_text}\"";
131
        if (isset($title)) {
132
            $title = $this->encodeAttribute($title);
133
            $result .= " title=\"${title}\""; // $title already quoted
134
        }
135
        $result .= $attr;
136
        // srcset
137
        $result .= $this->addSrcSet($url);
138
        $result .= $this->empty_element_suffix;
139
140
        return $this->hashPart($result);
141
    }
142
143
    /**
144
     * Callback for referenced images.
145
     *
146
     * @param array $matches
147
     *
148
     * @return string
149
     */
150
    protected function _doImages_reference_callback($matches)
151
    {
152
        $whole_match = $matches[1];
153
        $alt_text = $matches[2];
154
        $link_id = strtolower($matches[3]);
155
156
        if ('' == $link_id) {
157
            $link_id = strtolower($alt_text); // for shortcut links like ![this][].
158
        }
159
160
        $alt_text = $this->encodeAttribute($alt_text);
161
        if (isset($this->urls[$link_id])) {
162
            $url = $this->encodeURLAttribute($this->urls[$link_id]);
163
            $result = "<img src=\"${url}\" alt=\"${alt_text}\"";
164
            if (isset($this->titles[$link_id])) {
165
                $title = $this->titles[$link_id];
166
                $title = $this->encodeAttribute($title);
167
                $result .= " title=\"${title}\"";
168
            }
169
            if (isset($this->ref_attr[$link_id])) {
170
                $result .= $this->ref_attr[$link_id];
171
            }
172
            // srcset
173
            $result .= $this->addSrcSet($url);
174
            $result .= $this->empty_element_suffix;
175
            $result = $this->hashPart($result);
176
        } else {
177
            // If there's no such link ID, leave intact:
178
            $result = $whole_match;
179
        }
180
181
        return $result;
182
    }
183
}
184