GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

IllustrationsPlugin::parseAndRenderIllustrations()   B
last analyzed

Complexity

Conditions 7
Paths 1

Size

Total Lines 88

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 57
CRAP Score 7.0002

Importance

Changes 0
Metric Value
dl 0
loc 88
ccs 57
cts 58
cp 0.9828
rs 7.3284
c 0
b 0
f 0
cc 7
nc 1
nop 1
crap 7.0002

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 * This file is part of the trefoil application.
4
 *
5
 * (c) Miguel Angel Gabriel <[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
namespace Trefoil\Plugins\Optional;
11
12
use Easybook\Events\EasybookEvents;
13
use Easybook\Events\ParseEvent;
14
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15
use Trefoil\Plugins\BasePlugin;
16
17
/**
18
 * Manage the illustrations in the book item.
19
 *
20
 * An illustration is a block delimited by '<<' and '<</' marks.
21
 *
22
 * Expected syntax:
23
 *
24
 * << ========= "This is the illustration caption" ========= {.optional-class}
25
 * . . . whatever Markdown or HTML content
26
 * <</ =================
27
 *
28
 * where the '=' in the opening and closing block marks are optional, just to visually
29
 * delimit the illustration, and one or several classes can be specified between
30
 * curly brackets.
31
 *
32
 * ATX-style headers can be used inside of the illustration content and
33
 * will not be parsed by easybook (i.e. not added labels and ignored in the TOC).
34
 *
35
 * WARNINGS:
36
 *
37
 *  - When enabled, this functionality will take over the "tables" numbering
38
 *    and listing of easybook. If a table is needed as an illustration it will
39
 *    need to be done with this new markup.
40
 *    Ordinary tables (outside an illustration markup) will be ignored and just
41
 *    parsed as Markdown tables, not easybook tables.
42
 *
43
 *  - It needs the "lot.twig" templates present in the theme if used.
44
 *
45
 *  - Illustration HTML can be customized with "illustration.twig" template, but
46
 *    the plugin will apply a default HTML if the template is not present.
47
 *
48
 */
49
class IllustrationsPlugin extends BasePlugin implements EventSubscriberInterface
50
{
51
    protected $illustrations = [];
52
53 2 View Code Duplication
    public static function getSubscribedEvents()
54
    {
55
        return [
56 2
            EasybookEvents::PRE_PARSE  => ['onItemPreParse', -100],
57 2
            EasybookEvents::POST_PARSE => ['onItemPostParse', -1100]
58 2
        ];
59
    }
60
61
    /**
62
     * @param ParseEvent $event
63
     */
64 2 View Code Duplication
    public function onItemPreParse(ParseEvent $event)
65
    {
66 2
        $this->init($event);
67
68 2
        $content = $event->getItemProperty('original');
69
70 2
        $content = $this->parseAndRenderIllustrations($content);
71
72 2
        $event->setItemProperty('original', $content);
73 2
    }
74
75 2
    public function onItemPostParse(ParseEvent $event)
76
    {
77 2
        $this->init($event);
78
79 2
        $content = $event->getItemProperty('content');
80
81 2
        $this->replaceTablesWithIllustrations();
82
83 2
        $event->setItemProperty('content', $content);
84 2
    }
85
86
    /**
87
     * Parse illustrations and convert them to HTML.
88
     *
89
     * @param $content
90
     *
91
     * @return mixed
92
     */
93 2
    protected function parseAndRenderIllustrations($content)
94
    {
95 2
        $this->app['publishing.active_item.illustrations'] = [];
96
97 2
        $addIllustrationsLabels = in_array('illustration', $this->app->edition('labels') ?: array());
98 2
        $listOfTables = [];
99 2
        $parentItemNumber = $this->item['config']['number'];
100 2
        $counter = 0;
101
102 2
        $regExp = '/';
103 2
        $regExp .= '^<<'; // block opening
104 2
        $regExp .= '(?<p1> +=+)?'; // caption previous delimiter (optional)
105 2
        $regExp .= ' +"(?<caption>.*)"'; // caption
106 2
        $regExp .= '(?<p2>[ =]*)(?=[\n{])'; // caption post delimiter (optional)
107 2
        $regExp .= '(?<classGroup>\{(?<class>.*)\}.*)??'; // class (optional)
108 2
        $regExp .= '(?<data>.*)'; // text inside the block
109 2
        $regExp .= '^<<\/'; // block closing
110 2
        $regExp .= '(?<p3>.*)?$'; // closing delimiter (optional)
111 2
        $regExp .= '/Ums'; // Ungreedy, multiline, dotall
112
113 2
        $content = preg_replace_callback(
114 2
            $regExp,
115
            function ($matches) use ($parentItemNumber, &$addIllustrationsLabels, &$listOfTables, &$counter) {
116
117 2
                $caption = $matches['caption'];
118
119 2
                $data = $this->preProcessHeaders($matches['data']);
120
                
121 2
                $counter++;
122
123 2
                $slug = $this->app->slugify('Illustration ' . $parentItemNumber . '-' . $counter);
124
125
                $parameters = array(
126
                    'item'    => array(
127 2
                        'caption' => $caption,
128 2
                        'content' => $data,
129 2
                        'label'   => '',
130 2
                        'number'  => $counter,
131 2
                        'slug'    => $slug,
132 2
                    ),
133
                    'element' => array(
134 2
                        'number' => $parentItemNumber,
135 2
                    ),
136 2
                );
137
138
                // the publishing edition wants to label illustrations
139 2
                $label = '';
140 2
                if ($addIllustrationsLabels) {
141 2
                    if (isset($this->app['labels']['label']['illustration'])) {
142 2
                        $label = $this->app->getLabel('illustration', $parameters);
143 2
                    } else {
144
                        $label = $this->app->getLabel('table', $parameters);
145
                    }
146 2
                }
147
148 2
                $listOfTables[] = $parameters;
149
150 2
                $classes = implode(' ', explode(' ', str_replace('.', ' ', $matches['class'])));
151
                
152
                // complete the template parameters
153 2
                $parameters['item']['label'] = $label;
154 2
                $parameters['item']['classes'] = $classes;
155
                
156
                try {
157
                    // render with a template
158 2
                    return $this->app->render('illustration.twig', $parameters);
159 2
                } catch (\Twig_Error_Loader $e) {
160
                    // render anyway with a string
161 2
                    return sprintf(
162
                        '<div class="illustration%s" markdown="1" id="%s"><blockquote markdown="1">' .
163 2
                        '<div class="caption" markdown="1">%s%s<hr/></div>' .
164 2
                        '<div class="content" markdown="1">%s</div>' .
165 2
                        '</blockquote></div>',
166 2
                        $parameters['item']['classes'] ? ' ' . $parameters['item']['classes'] : '',
167 2
                        $parameters['item']['slug'],
168 2
                        $parameters['item']['label'] ? $parameters['item']['label']. ' - ' : '',
169 2
                        $parameters['item']['caption'],
170 2
                        $parameters['item']['content']
171 2
                    );
172
                }
173 2
            },
174
            $content
175 2
        );
176
177 2
        $this->app['publishing.active_item.illustrations'] = $listOfTables;
178
179 2
        return $content;
180
    }
181
182
    /**
183
     * Convert the ATX Markdown headers inside the illustration to HTML
184
     * to keep easybook from parsing them (so it does not add labels and ids).
185
     *
186
     * @param $content
187
     *
188
     * @return mixed
189
     */
190 2
    protected function preProcessHeaders($content)
191
    {
192 2
        $regExp = '/';
193 2
        $regExp .= '^(?<atx>#{5,6}) '; // atx header
194 2
        $regExp .= '(?<htext>.*)$'; // header text/rest
195 2
        $regExp .= '/Ums'; // Ungreedy, multiline, dotall
196
197 2
        $content = preg_replace_callback(
198 2
            $regExp,
199 2
            function ($matches) {
200
201 2
                $level = strlen($matches['atx']);
202
203 2
                $html = sprintf(
204 2
                    '<p class="heading" markdown="1">%s%s%s</p>',
205 2
                    $level == 5 ? '**' : '*',
206 2
                    $matches['htext'],
207 2
                    $level == 5 ? '**' : '*'
208 2
                );
209
210 2
                return $html;
211 2
            },
212
            $content
213 2
        );
214
215 2
        return $content;
216
    }
217
    
218
    /**
219
     * Replace all tables (in the internal list of tables) in the current item
220
     * with the detected illustrations.
221
     */
222 2
    protected function replaceTablesWithIllustrations()
223 2
    {
224 2
        $newTables = [];
225
226
        // filter out the tables of this item
227 2
        foreach ($this->app['publishing.list.tables'] as $itemTables) {
228 2
            $newItemTables = [];
229
230 2
            foreach ($itemTables as $table) {
231 2
                if ($table['element']['number'] !== $this->item['config']['number']) {
232 2
                    $newItemTables[] = $table;
233 2
                }
234 2
            }
235
236 2
            if (count($newItemTables)) {
237 2
                $newTables[] = $newItemTables;
238 2
            }
239 2
        }
240
241
        // and append the illustrations of this item
242 2
        $this->app['publishing.list.tables'] = $newTables;
243 2
        $this->app->append('publishing.list.tables', array_values($this->app['publishing.active_item.illustrations']));
244 2
    }
245
246
}
247