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.

QualityControlPlugin::onItemPostParse()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1.2963

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 2
cts 6
cp 0.3333
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1.2963
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\BaseEvent;
13
use Easybook\Events\EasybookEvents;
14
use Easybook\Events\ParseEvent;
15
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
16
use Symfony\Component\Finder\Finder;
17
use Trefoil\Plugins\BasePlugin;
18
use Trefoil\Util\SimpleReport;
19
20
/**
21
 * This plugin performs several checks on the finished book to help
22
 * fixing common problems.
23
 *
24
 * - Markdown emphasis marks (_ and *) not processed.
25
 * - Unused images.
26
 */
27
class QualityControlPlugin extends BasePlugin implements EventSubscriberInterface
28
{
29
    protected $images = array();
30
    protected $problems = array();
31
    protected $problemsFound = false;
32
33 1
    public static function getSubscribedEvents()
34
    {
35
        return array(
36
            //EasybookEvents::POST_PARSE   => array('onItemPostParse', -9999), // Latest
37 1
            EasybookEvents::POST_DECORATE => array('onItemPostDecorate', -9999), // Latest
38 1
            EasybookEvents::POST_PUBLISH  => 'onPostPublish'
39 1
        );
40
    }
41
42
    /* ********************************************************************************
43
     * Event handlers
44
    * ********************************************************************************
45
    */
46 1
    public function onItemPostParse(ParseEvent $event)
47
    {
48
        $this->init($event);
49
50 1
        $content = $event->getItemProperty('content');
51
52
        $this->checkImages($content);
53
        $this->checkEmphasis($content);
54
    }
55
56 1
    public function onItemPostDecorate(BaseEvent $event)
57
    {
58 1
        $this->init($event);
59
60 1
        $content = $this->item['content'];
61
62 1
        $this->checkImages($content);
63 1
        $this->checkEmphasis($content);
64 1
    }
65
66 1
    public function onPostPublish(BaseEvent $event)
67
    {
68 1
        $this->init($event);
69
70 1
        $this->createReport();
71
72 1
        $this->writeResultsMessage();
73 1
    }
74
75
    /* ********************************************************************************
76
     * Implementation
77
    * ********************************************************************************
78
    */
79 1
    public function checkImages($content)
80
    {
81 1
        $images = $this->extractImages($content);
82
83 1
        foreach ($images as $image) {
84
            // save it for later check
85 1
            $this->saveImage($image);
86 1
        }
87 1
    }
88
89
    /**
90
     * Extracts all images in the string
91
     *
92
     * @param string $string
93
     *
94
     * @return array of images
95
     */
96 1
    protected function extractImages($string)
97
    {
98
        // find all the images
99 1
        $regExp = '/<img(.*)\/?>/Us';
100 1
        preg_match_all($regExp, $string, $imagesMatch, PREG_SET_ORDER);
101
102 1
        $images = array();
103
104 1
        if ($imagesMatch) {
105 1
            foreach ($imagesMatch as $imageMatch) {
106
                // get all attributes
107 1
                $regExp2 = '/(?<attr>.*)="(?<value>.*)"/Us';
108 1
                preg_match_all($regExp2, $imageMatch[1], $attrMatches, PREG_SET_ORDER);
109
110 1
                $attributes = array();
111
112 1
                if ($attrMatches) {
113 1
                    foreach ($attrMatches as $attrMatch) {
114 1
                        $attributes[trim($attrMatch['attr'])] = $attrMatch['value'];
115 1
                    }
116 1
                }
117
118 1
                $images[] = $attributes;
119 1
            }
120 1
        }
121
122 1
        return $images;
123
    }
124
125 1
    public function checkEmphasis($content)
126
    {
127
128
        // process all the paragraphs
129 1
        $regExp = '/';
130 1
        $regExp .= '<p>(?<par>.*)<\/p>';
131 1
        $regExp .= '/Ums'; // Ungreedy, multiline, dotall
132 1
        preg_match_all($regExp, $content, $matches, PREG_SET_ORDER);
133
134 1
        if ($matches) {
135 1
            foreach ($matches as $match) {
136 1
                $emphasis = $this->extractEmphasis($match['par']);
137 1
                foreach ($emphasis as $emph) {
138 1
                    if (in_array($emph, array('(*)', '"*"'))) {
139
                        // common strings
140 1
                        continue;
141
                    }
142 1
                    if (false !== strpos($emph, '__')) {
143
                        // a line draw with underscores
144
                        continue;
145
                    }
146
147 1
                    $this->saveProblem($emph, 'emphasis', 'Emphasis mark not processed');
148 1
                }
149 1
            }
150 1
        }
151 1
    }
152
153 1
    protected function extractEmphasis($string)
154
    {
155 1
        $noBlanks = '[\w\.,\-\(\)\:;"]';
156
157
        // find all the Markdown emphasis marks that have made it out to HTML
158 1
        $regExp = '/(?<em>'; // start capturing group
159 1
        $regExp .= '\s[_\*]+(?:[^\s_\*]+?)'; // underscore or asterisk after a space
160 1
        $regExp .= '|';
161 1
        $regExp .= '(?:[^\s_\*]+)[_\*]+\s'; // underscore or asterisk before a space
162 1
        $regExp .= '|';
163 1
        $regExp .= '(?:\s(?:_|\*{1,2})\s)'; // underscore or asterisk or double asterisk surrounded by spaces
164 1
        $regExp .= '|';
165 1
        $regExp .= '^(?:[_\*]+\s.*$)'; // underscore or asterisk before a space at start of line
166 1
        $regExp .= '|';
167 1
        $regExp .= '(?:' . $noBlanks . '+\*+' . $noBlanks . '+)'; // asterisk between no spaces
168 1
        $regExp .= ')/Ums'; // Ungreedy, multiline, dotall
169 1
        preg_match_all($regExp, $string, $matches, PREG_SET_ORDER);
170
171 1
        $emphasis = array();
172
173 1
        if ($matches) {
174 1
            foreach ($matches as $match) {
175 1
                $emphasis[] = $match['em'];
176 1
            }
177 1
        }
178
179 1
        return $emphasis;
180
    }
181
182 1
    protected function saveProblem($object, $type, $message)
183
    {
184 1
        $problem = array();
185
186 1
        $problem['object'] = $object;
187 1
        $problem['type'] = $type;
188 1
        $problem['message'] = $message;
189
190 1
        $element = $this->item['config']['content'];
191 1
        $element = $element ? $element : $this->item['config']['element'];
192 1
        if (!isset($this->problems[$element])) {
193 1
            $this->problems[$element] = array();
194 1
        }
195
196 1
        $this->problems[$element][] = $problem;
197 1
    }
198
199 1
    protected function createReport()
200
    {
201
        // create the report
202 1
        $outputDir = $this->app['publishing.dir.output'];
203 1
        $reportFile = $outputDir . '/report-QualityControlPlugin.txt';
204
205 1
        $report = '';
206 1
        $report .= $this->getProblemsReport();
207 1
        $report .= '';
208 1
        $report .= $this->getImagesNotUsedReport();
209
210 1
        file_put_contents($reportFile, $report);
211 1
    }
212
213 1
    protected function saveImage($image)
214
    {
215 1
        if (!isset($this->images[$image['src']])) {
216 1
            $this->images[$image['src']] = 0;
217 1
        }
218
219 1
        $this->images[$image['src']]++;
220 1
    }
221
222 1
    protected function getProblemsReport()
223
    {
224 1
        $report = new SimpleReport();
225 1
        $report->setTitle('QualityControlPlugin');
226 1
        $report->setSubtitle('Problems found');
227
228 1
        $report->setHeaders(array('Element', 'Type', 'Object', 'Message'));
229 1
        $report->setColumnsWidth(array(10, 10, 30, 100));
230
231 1
        $count = 0;
232 1
        foreach ($this->problems as $element => $problems) {
233 1
            $report->addLine();
234 1
            $report->addLine($element);
235 1
            $report->addLine();
236 1
            foreach ($problems as $problem) {
237 1
                $count++;
238 1
                $report->addLine(
239
                    array(
240 1
                        '',
241 1
                        $problem['type'],
242 1
                        substr($problem['object'], 0, 30),
243 1
                        $problem['message'])
244 1
                );
245 1
            }
246 1
        }
247
248 1 View Code Duplication
        if ($count == 0) {
249
            $report->addSummaryLine('No problems found');
250
        } else {
251 1
            $report->addSummaryLine(sprintf('%s problems found', $count));
252 1
            $this->problemsFound = true;
253
        }
254
255 1
        return $report->getText();
256
    }
257
258 1
    protected function getImagesNotUsedReport()
259
    {
260 1
        $report = new SimpleReport();
261 1
        $report->setTitle('QualityControlPlugin');
262 1
        $report->setSubtitle('Images not used');
263
264 1
        $report->setHeaders(array('Image'));
265 1
        $report->setColumnsWidth(array(100));
266
267
        // check existing images
268 1
        $imagesDir = $this->app['publishing.dir.contents'] . '/images';
269
270 1
        $existingImages = array();
271
272 1
        if (file_exists($imagesDir)) {
273 1
            $existingFiles = Finder::create()->files()->in($imagesDir)->sortByName();
274
275 1
            foreach ($existingFiles as $image) {
276 1
                $name = str_replace($this->app['publishing.dir.contents'] . '/', '', $image->getPathname());
277 1
                $existingImages[] = $name;
278 1
            }
279 1
        }
280
281 1
        $count = 0;
282 1
        foreach ($existingImages as $image) {
283 1
            if (!isset($this->images[$image])) {
284 1
                $count++;
285 1
                $report->addLine(array($image));
286 1
            }
287 1
        }
288
289 1 View Code Duplication
        if ($count == 0) {
290
            $report->addSummaryLine('No unused images');
291
        } else {
292 1
            $report->addSummaryLine(sprintf('%s unused images found', $count));
293 1
            $this->problemsFound = true;
294
        }
295
296 1
        return $report->getText();
297
    }
298
299
    /**
300
     * Write a message to the user about problems found.
301
     */
302 1
    protected function writeResultsMessage()
303
    {
304 1
        if (!$this->problemsFound) {
305
            $this->writeLn('No quality problems');
306
        } else {
307 1
            $this->writeLn('Some quality problems detected', 'warning');
308
        }
309 1
    }
310
}
311