MarkdownEngine   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 26.09%

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 3
dl 0
loc 146
ccs 12
cts 46
cp 0.2609
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
B inlineImage() 0 22 6
A slugifyHeader() 0 8 1
A setAllowImages() 0 4 1
A blockHeader() 0 11 2
A blockSetextHeader() 0 16 4
A inlineLink() 0 14 3
A __construct() 0 11 2
1
<?php
2
/**
3
 * This file contains functionality related to parsing Markdown across BZiON
4
 *
5
 * @package    BZiON
6
 * @license    https://github.com/allejo/bzion/blob/master/LICENSE.md GNU General Public License Version 3
7
 */
8
9
namespace BZIon;
10
11
/**
12
 * This class extends Parsedown and adds functionality to enable or disable functionality
13
 */
14
class MarkdownEngine extends \Parsedown
15
{
16
    /**
17
     * Whether or not to allow images to be rendered. If set to false, it'll be rendered as a hyperlink
18
     * @var bool
19
     */
20
    protected $allowImages;
21
22
    /**
23
     * Store all of the settings related to Camo
24
     * @var array
25
     */
26
    private $camo;
27
28
    /**
29
     * Constructor for our extension of Parsedown
30
     */
31 1
    public function __construct()
32
    {
33 1
        $this->camo = array();
34 1
        $this->camo['enabled'] = \Service::getParameter('bzion.features.camo.enabled');
35
36 1
        if ($this->camo['enabled']) {
37
            $this->camo['key'] = \Service::getParameter('bzion.features.camo.key');
38
            $this->camo['base_url'] = \Service::getParameter('bzion.features.camo.base_url');
39
            $this->camo['whitelisted_domains'] = \Service::getParameter('bzion.features.camo.whitelisted_domains');
40
        }
41 1
    }
42
43
    /**
44
     * Overload the function to either return nothing (if image image rendering is disable) or return the
45
     * rendered image by calling the Parsedown function
46
     *
47
     * @param string $Excerpt The excerpt of text to be processed as an image
48
     *
49
     * @return array|null|void
50
     */
51
    protected function inlineImage($Excerpt)
52
    {
53
        if ($this->allowImages) {
54
            $Image = parent::inlineImage($Excerpt);
55
56
            if ($this->camo['enabled']) {
57
                $parts = parse_url($Image['element']['attributes']['src']);
58
59
                if (!isset($parts['host']) || strlen($parts['host']) === 0) {
60
                    return null;
61
                }
62
63
                if (!in_array($parts['host'], $this->camo['whitelisted_domains'])) {
64
                    $Image['element']['attributes']['src'] = $this->camo['base_url'] . hash_hmac('sha1', $Image['element']['attributes']['src'], $this->camo['key']) . '/' . bin2hex($Image['element']['attributes']['src']);
65
                }
66
            }
67
68
            return $Image;
69
        }
70
71
        return null;
72
    }
73
74
    /**
75
     * Overload the function replace the scheme + host of the link if belongs to the current website serving the link.
76
     * This will prevent CSS rules from treating full URLs as external links.
77
     *
78
     * @param array $Excerpt The structure of the link to be processed
79
     *
80
     * @return array
81
     */
82
    protected function inlineLink($Excerpt)
83
    {
84
        $link = parent::inlineLink($Excerpt);
85
86
        if (isset($link['element']['attributes']['href'])) {
87
            $href = &$link['element']['attributes']['href'];
88
89
            if (strpos($href, $scheme = \Service::getRequest()->getSchemeAndHttpHost()) === 0) {
90
                $href = str_replace($scheme, '', $href);
91
            }
92
        }
93
94
        return $link;
95
    }
96
97
    /**
98
     * Overload this function to add IDs to the headings (with pound signs) so they can be used as anchors
99
     *
100
     * @param array $Line
101
     *
102
     * @return array|null
103
     */
104
    protected function blockHeader($Line)
105
    {
106
        $Block = parent::blockHeader($Line);
107
108
        if (isset($Block['element']['text']))
109
        {
110
            $Block['element']['attributes']['id'] = $this->slugifyHeader($Block);
111
        }
112
113
        return $Block;
114
    }
115
116
    /**
117
     * Overload this function to add IDs to headings (with horizontal dashes) so they can be used as anchors
118
     *
119
     * @param array $Line
120
     * @param array|null $Block
121
     *
122
     * @return array|null
123
     */
124 1
    protected function blockSetextHeader($Line, array $Block = null)
125
    {
126 1
        $Block = parent::blockSetextHeader($Line, $Block);
127
128 1
        if (isset($Block['element']['name']))
129
        {
130
            $element = $Block['element']['name'];
131
132
            if ($element == 'h1' || $element == 'h2')
133
            {
134
                $Block['element']['attributes']['id'] = $this->slugifyHeader($Block);
135
            }
136
        }
137
138 1
        return $Block;
139
    }
140
141
    private function slugifyHeader($Block)
142
    {
143
        $id = strtolower($Block['element']['text']);
144
        $id = str_replace(' ', '-', $id);
145
        $id = preg_replace('/[^0-9a-zA-Z-_]/', '', $id);
146
147
        return preg_replace('/-+/', '-', $id);
148
    }
149
150
    /**
151
     * Disable or enable Parsedown from rendering images
152
     *
153
     * @param bool $allowImages Whether to allow images to be rendered or not
154
     */
155 1
    public function setAllowImages($allowImages)
156
    {
157 1
        $this->allowImages = $allowImages;
158 1
    }
159
}
160