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.

TableExtra::processMultilineCells()   C
last analyzed

Complexity

Conditions 12
Paths 91

Size

Total Lines 70

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 42
CRAP Score 12.0018

Importance

Changes 0
Metric Value
dl 0
loc 70
ccs 42
cts 43
cp 0.9767
rs 6.2278
c 0
b 0
f 0
cc 12
nc 91
nop 1
crap 12.0018

How to fix   Long Method    Complexity   

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
11
namespace Trefoil\Helpers;
12
13
use Easybook\Parsers\ParserInterface;
14
15
/**
16
 * This class:
17
 * - For headless tables, transforms the <td> cells in first column
18
 *   within <strong> tags into <th> cells (making a vertical head).
19
 * - Allows multiline cells.
20
 *
21
 * Multiline cells:
22
 * ---------------
23
 *
24
 * If a line inside a cell ends with '+' char (plus sign) it will be joined
25
 * with the next line.
26
 *
27
 * Automatic head cells for headless tables:
28
 * ----------------------------------------
29
 *
30
 * For a headless table (i.e. without headings in first row), cells in first
31
 * column that are all bold (i.e. surrounded by "**") will be rendered
32
 * as "<th>" tags instead of normal "<td>" tags, allowing formatting.
33
 *
34
 */
35
class TableExtra
36
{
37
    /** @var  ParserInterface */
38
    protected $markdownParser;
39
40
    /**
41
     * @param ParserInterface $markdownParser
42
     */
43 1
    public function setMarkdownParser($markdownParser)
44
    {
45 1
        $this->markdownParser = $markdownParser;
46 1
    }
47
48
    /**
49
     * Processes all tables in the html string
50
     *
51
     * @param string $htmlString
52
     *
53
     * @return string
54
     */
55 3
    public function processAllTables($htmlString)
56
    {
57 3
        $regExp = '/';
58 3
        $regExp .= '(?<table><table.*<\/table>)';
59 3
        $regExp .= '/Ums'; // Ungreedy, multiline, dotall
60
61
        // PHP 5.3 compat
62 3
        $me = $this;
63
64 3
        $callback = function ($matches) use ($me) {
65 3
            $table = new Table();
66 3
            $table->fromHtml($matches['table']);
67
68 3
            if ($table->isEmpty()) {
69
                return $matches[0];
70
            }
71
72 3
            $table = $me->internalProcessExtraTable($table);
73 3
            $html = $table->toHtml();
74
75 3
            return $html;
76 3
        };
77
78 3
        $output = preg_replace_callback($regExp, $callback, $htmlString);
79
80 3
        return $output;
81
    }
82
83
    /**
84
     * @param Table $table
85
     *
86
     * @return Table
87
     * @internal Should be protected but made public for PHP 5.3 compat
88
     */
89 3
    public function internalProcessExtraTable(Table $table)
90
    {
91
        // process and adjusts table definition
92
93 3
        $headless = true;
94 3
        foreach ($table['thead'] as $row) {
95 2
            foreach ($row as $cell) {
96 2
                if (empty($cell['contents'])) {
97 2
                    $headless = true;
98 2
                    break 2;
99
                }
100 2
            }
101 3
        }
102
103
        // headless table
104 3
        if ($headless && $table['tbody']) {
105 3
            $table['tbody'] = $this->processFirstColumnCells($table['tbody']);
106 3
        }
107
108
        // table with head and body
109 3
        if ($table['thead'] || $table['tbody']) {
110
111 3
            $table['thead'] = $this->processMultilineCells($table['thead']);
112 3
            $table['tbody'] = $this->processMultilineCells($table['tbody']);
113
114 3
            return $table;
115
        }
116
117
        // table without head or body
118
        $table['table'] = $this->processMultilineCells($table['table']);
119
120
        return $table;
121
    }
122
123
    /**
124
     * Join the cells that belong to multiline cells.
125
     *
126
     * @param $rows
127
     *
128
     * @return array Processed table rows
129
     */
130 3
    protected function processMultilineCells(array $rows)
131
    {
132 3
        $newRows = $rows;
133 3
        foreach ($newRows as $rowIndex => $row) {
134
135 3
            foreach ($row as $colIndex => $col) {
136 3
                $cell = $newRows[$rowIndex][$colIndex];
137 3
                $cellText = rtrim($cell['contents']);
138
139 3
                if (substr($cellText, -1, 1) === '+') {
140
                    // continued cell
141 1
                    $newCell = array();
142 1
                    $newCell[] = substr($cellText, 0, -1);
143
144
                    // find all the continuation cells (same col)
145 1
                    for ($nextRowIndex = $rowIndex + 1; $nextRowIndex < count($newRows); $nextRowIndex++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
146
147 1
                        $nextCell = $newRows[$nextRowIndex][$colIndex];
148 1
                        $cellText = rtrim($nextCell['contents']);
149
150 1
                        $newRows[$nextRowIndex][$colIndex]['contents'] = '';
151
152
                        // continued cell?
153 1
                        $continued = (substr($cellText, -1, 1) === '+');
154
155 1
                        if ($continued) {
156
                            // clean the ending (+)
157 1
                            $cellText = substr($cellText, 0, -1);
158 1
                        }
159
160
                        // save cleaned text
161 1
                        $newCell[] = $cellText;
162
163 1
                        if (!$continued) {
164
                            // no more continuations
165 1
                            break;
166
                        }
167 1
                    }
168
169 1
                    if ($this->markdownParser) {
170 1
                        $parsedCell = $this->markdownParser->transform(join("\n\n", $newCell));
171 1
                    } else {
172
                        // safe default
173
                        $parsedCell = join("<br/>", $newCell);
174
                    }
175
176 1
                    $newRows[$rowIndex][$colIndex]['contents'] = $parsedCell;
177 1
                }
178 3
            }
179 3
        }
180
181
        // remove empty rows left by the process
182 3
        $newRows2 = array();
183 3
        foreach ($newRows as $rowIndex => $row) {
184
185 3
            $emptyRow = true;
186 3
            foreach ($row as $colIndex => $col) {
187 3
                $cellText = trim($col['contents']);
188 3
                if (!empty($cellText)) {
189 3
                    $emptyRow = false;
190 3
                }
191 3
            }
192
193 3
            if (!$emptyRow) {
194 3
                $newRows2[] = $row;
195 3
            }
196 3
        }
197
198 3
        return $newRows2;
199
    }
200
201
    /**
202
     * Converts <td> cells into <th> for first column cells that are fully bold.
203
     *
204
     * @param array $rows
205
     *
206
     * @return array Processed rows
207
     */
208 3
    protected function processFirstColumnCells(array $rows)
209
    {
210 3
        $newRows = $rows;
211 3
        foreach ($newRows as $rowIndex => $row) {
212
213
            // examine first cell ir row
214 3
            $cell = $newRows[$rowIndex][0];
215 3
            $cellText = rtrim($cell['contents']);
216
217 3
            $regExp = '/^<strong>.*<\/strong>$/Us';
218 3
            if (preg_match($regExp, $cellText, $matches)) {
219 1
                $cell['tag'] = 'th';
220
221
                // change cell to <th>  
222 1
                $newRows[$rowIndex][0]['tag'] = 'th';
223 1
            }
224 3
        }
225
226 3
        return $newRows;
227
    }
228
229
}
230