Passed
Push — master ( 395129...4a18b4 )
by Patrick
01:56
created

TrapDirectorTable   F

Complexity

Total Complexity 63

Size/Duplication

Total Lines 429
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 173
c 2
b 0
f 1
dl 0
loc 429
rs 3.36
wmc 63

27 Methods

Rating   Name   Duplication   Size   Complexity  
A render() 0 15 1
A countQuery() 0 9 1
A renderFilter() 0 12 1
A __construct() 0 12 1
A curOrderQuery() 0 4 2
A setMaxPerPage() 0 3 1
A setFilter() 0 5 1
A getFilterQuery() 0 6 2
A curPagingQuery() 0 4 2
A renderTitles() 0 33 5
A fullQuery() 0 8 1
A curFilterQuery() 0 4 2
A renderLine() 0 11 2
B getCurrentURLAndQS() 0 17 9
A getPagingQuery() 0 5 2
A applyPaging() 0 4 1
A getBaseQuery() 0 9 1
A getParams() 0 5 1
A setOrder() 0 4 1
A renderTable() 0 11 2
A applyOrder() 0 16 4
A titleOrder() 0 3 1
A getOrderQuery() 0 11 3
B renderPagingHeader() 0 76 9
A getCurrentURL() 0 3 1
A count() 0 4 1
A applyFilter() 0 18 5

How to fix   Complexity   

Complex Class

Complex classes like TrapDirectorTable often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use TrapDirectorTable, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Icinga\Module\Trapdirector\Tables;
4
5
6
abstract class TrapDirectorTable
7
{
8
    /** @var array $titles table titles (name, display value) */
9
    protected $titles = null;
10
11
    /** @var array $content table content  (name, sb column name). name index must be the same as $titles*/
12
    protected $content = null;
13
    
14
    /** @var array $columnNames names of columns for filtering */
15
    protected $columnNames = array();
16
    
17
    /** @var mixed $dbConn connection to database  */
18
    protected $dbConn = null;
19
    
20
    /** Current view **/
21
    protected $view;
22
    
23
    protected $urlPath;
24
    
25
    // Database stuff
26
   /** @var array $table (db ref, name) */
27
    protected $table = array();
28
    
29
    /** @var mixed  $query Query in database; */
30
    protected $query = null;
31
    
32
    /** @var array $order : (db column, 'ASC' | 'DESC') */
33
    protected $order = array();
34
    protected $orderQuery = '';
35
    
36
    /********* Filter ********/
37
    /** @var string $filterString : string filter for db columns */
38
    protected $filterString = '';
39
    
40
    /** @var array $filterColumn : columns to apply filter to */
41
    protected $filterColumn = array();
42
    
43
    protected $filterQuery='';
44
    
45
    /*************** Paging *************/
46
    protected $maxPerPage = 25;
47
    
48
    protected $currentPage = 0;
49
    
50
    function __construct(array $table,array $titles, array $columns, array $columnNames, $dbConn , $view, $urlPath)
51
    {
52
        $this->table = $table;
53
        $this->titles = $titles;
54
        $this->content = $columns;
55
        $this->columnNames = $columnNames;
56
        $this->dbConn = $dbConn;
57
        
58
        $this->view = $view;
59
        $this->urlPath = $urlPath;
60
        
61
        return $this;
62
    }
63
64
    
65
    /************** GET variables and URLs *************/
66
    public function getParams(array $getVars)
67
    {
68
        $this->getFilterQuery($getVars);
69
        $this->getPagingQuery($getVars);
70
        $this->getOrderQuery($getVars);
71
    }
72
    
73
    public function getCurrentURL()
74
    {
75
        return '?';
76
    }
77
    
78
    protected function getCurrentURLAndQS(string $caller)
79
    {
80
        $actionURL = $this->getCurrentURL() . '?' ;
81
        $QSList=array();
82
        if ($caller != 'filter' && $this->curFilterQuery() != '')
83
            array_push($QSList , $this->curFilterQuery());
84
        
85
        if ($caller != 'paging' && $caller != 'filter' && $this->curPagingQuery() != '')
86
            array_push($QSList , $this->curPagingQuery());
87
 
88
        if ($caller != 'order' && $this->curOrderQuery() != '')
89
            array_push($QSList , $this->curOrderQuery());
90
        
91
        if (count($QSList) != 0)
92
            $actionURL .=  implode('&', $QSList);
93
        
94
        return $actionURL;
95
    }
96
    
97
    /************* DB queries ******************/
98
    /**
99
     * Get base query in $this->query
100
     * @return  TrapDirectorTable
101
     */
102
    public function getBaseQuery()
103
    {
104
        $this->query = $this->dbConn->select();
105
        $this->query = $this->query->from(
106
            $this->table,
107
            $this->content
108
            );
109
        
110
        return $this;
111
    }
112
    
113
    public function fullQuery()
114
    {
115
        $this->getBaseQuery()
116
        ->applyFilter()
117
        ->applyPaging()
118
        ->applyOrder();
119
        
120
        return $this->dbConn->fetchAll($this->query);
121
        //return $this->query->fetchAll();
122
    }
123
    
124
    
125
    /**************** Filtering ******************/
126
    
127
    public function applyFilter()
128
    {
129
        if ($this->filterString == '' || count($this->filterColumn) == 0)
130
        {
131
            return $this;
132
        }
133
        $filter='';
134
        foreach ($this->filterColumn as $column)
135
        {
136
            if ($filter != "") $filter.=' OR ';
137
            //$filter .= "'" . $column . "' LIKE '%" . $this->filterString. "%'";
138
            $filter .= $column  . " LIKE '%" . $this->filterString. "%'";
139
        }
140
        //echo $filter;
141
        
142
        $this->query=$this->query->where($filter);
143
144
        return $this;
145
    }
146
147
    public function setFilter(string $filter, array $filterCol)
148
    {
149
        $this->filterString = $filter;
150
        $this->filterColumn = $filterCol;
151
        return $this;
152
    }
153
   
154
    public function renderFilter()
155
    {
156
        
157
        $html=' <form id="genfilter" name="mainFilterGen"
158
			enctype="application/x-www-form-urlencoded"
159
			action="'.$this->getCurrentURLAndQS('filter').'"
160
			method="get">';
161
        $html.='<input type="text" name="f" title="Search is simple! Try to combine multiple words"
162
	placeholder="Search..."  value="'.$this->filterQuery.'">';
163
164
        $html.='</form>';
165
        return $html;
166
    }
167
 
168
    public function getFilterQuery(array $getVars)
169
    {
170
        if (isset($getVars['f']))
171
        {
172
            $this->filterQuery = $getVars['f'];
173
            $this->setFilter(html_entity_decode($getVars['f']), $this->columnNames);
174
        }
175
    }
176
    
177
    protected function curFilterQuery()
178
    {
179
        if ($this->filterQuery == '') return '';
180
        return 'f='.$this->filterQuery;
181
    }
182
    
183
    /***************** Ordering ********************/
184
    
185
    public function applyOrder()
186
    {
187
        if (count($this->order) == 0)
188
        {
189
            return $this;
190
        }
191
        $orderSQL='';
192
        foreach ($this->order as $column => $direction)
193
        {
194
            if ($orderSQL != "") $orderSQL.=',';
195
            
196
            $orderSQL .= $column . ' ' . $direction;
197
        }
198
        $this->query = $this->query->order($orderSQL);
199
        
200
        return $this;
201
    }
202
    
203
    public function setOrder(array $order)
204
    {
205
        $this->order = $order;
206
        return $this;
207
    }
208
    
209
    public function getOrderQuery(array $getVars)
210
    {
211
        if (isset($getVars['o']))
212
        {
213
            $this->orderQuery = $getVars['o'];
214
            $match = array();
215
            if (preg_match('/(.*)(ASC|DESC)$/', $this->orderQuery , $match))
216
            {
217
                $orderArray=array($match[1] => $match[2]);
218
                echo "$match[1] => $match[2]";
219
                $this->setOrder($orderArray);
220
            }
221
        }
222
    }
223
    
224
    protected function curOrderQuery()
225
    {
226
        if ($this->orderQuery == '') return '';
227
        return 'o='.$this->orderQuery;
228
    }
229
    
230
    /*****************  Paging and counting *********/
231
    
232
    public function countQuery()
233
    {
234
        $this->query = $this->dbConn->select();
235
        $this->query = $this->query
236
            ->from(
237
                $this->table,
238
                array('COUNT(*)')
239
                );
240
        $this->applyFilter();                   
241
    }
242
    
243
    public function count()
244
    {
245
        $this->countQuery();
246
        return $this->dbConn->fetchOne($this->query);
247
    }
248
    
249
    public function setMaxPerPage(int $max)
250
    {
251
        $this->maxPerPage = $max;
252
    }
253
    
254
    protected function getPagingQuery(array $getVars)
255
    {
256
        if (isset($getVars['page']))
257
        {
258
            $this->currentPage = $getVars['page'];
259
        }
260
    }
261
262
    protected function curPagingQuery()
263
    {
264
        if ($this->currentPage == '') return '';
265
        return 'page='.$this->currentPage;
266
    }
267
    
268
    public function renderPagingHeader()
269
    {
270
        $count = $this->count();
271
        if ($count <= $this->maxPerPage )
272
        {
273
            return  'count : ' . $this->count() . '<br>';
274
        }
275
        
276
        if ($this->currentPage == 0) $this->currentPage = 1;
277
        
278
        $numPages = intdiv($count , $this->maxPerPage);
279
        if ($count % $this->maxPerPage != 0 ) $numPages++;
280
        
281
        $html = '<div class="pagination-control" role="navigation">';
282
        $html .= '<ul class="nav tab-nav">';
283
        if ($this->currentPage <=1)
284
        {
285
            $html .= '
286
                <li class="nav-item disabled" aria-hidden="true">
287
                    <span class="previous-page">
288
                            <span class="sr-only">Previous page</span>
289
                            <i aria-hidden="true" class="icon-angle-double-left"></i>            
290
                     </span>
291
                </li>
292
               ';
293
        }
294
        else 
295
        {
296
            $html .= '
297
                <li class="nav-item">
298
                    <a href="'. $this->getCurrentURLAndQS('paging') .'&page='. ($this->currentPage - 1 ).'" class="previous-page" >
299
                            <i aria-hidden="true" class="icon-angle-double-left"></i>            
300
                     </a>
301
                </li>
302
            ';
303
        }
304
        
305
        for ($i=1; $i <= $numPages ; $i++)
306
        {
307
            $active = ($this->currentPage == $i) ? 'active' : '';
308
            $first = ($i-1)*$this->maxPerPage+1;
309
            $last = $i * $this->maxPerPage;
310
            if ($last > $count) $last = $count;
311
            $display = 'Show rows '. $first . ' to '. $last .' of '. $count;
312
            $html .= '<li class="' . $active . ' nav-item">
313
                    <a href="'. $this->getCurrentURLAndQS('paging') .'&page='. $i .'" title="' . $display . '" aria-label="' . $display . '">
314
                    '.$i.'                
315
                    </a>
316
                </li>';
317
        }
318
        
319
        if ($this->currentPage == $numPages)
320
        {
321
            $html .= '
322
                <li class="nav-item disabled" aria-hidden="true">
323
                    <span class="previous-page">
324
                            <span class="sr-only">Previous page</span>
325
                            <i aria-hidden="true" class="icon-angle-double-right"></i>
326
                     </span>
327
                </li>
328
               ';
329
        }
330
        else
331
        {
332
            $html .= '
333
                <li class="nav-item">
334
                    <a href="'. $this->getCurrentURLAndQS('paging') .'&page='. ($this->currentPage + 1 ).'" class="next-page">
335
                            <i aria-hidden="true" class="icon-angle-double-right"></i>
336
                     </a>
337
                </li>
338
            ';
339
        }
340
        
341
        $html .= '</ul> </div>';
342
        
343
        return $html;
344
    }
345
    
346
    public function applyPaging()
347
    {
348
        $this->query->limitPage($this->currentPage,$this->maxPerPage);
349
        return $this;
350
    }
351
    
352
    /*************** Rendering *************************/
353
    
354
    public function titleOrder($name)
355
    {
356
        return $this->content[$name];
357
    }
358
    
359
    public function renderTitles()
360
    {
361
        $html = "<thead>\n<tr>\n";
362
        foreach ($this->titles as $name => $values)
363
        {
364
            $titleOrder = $this->titleOrder($name);
365
            if ($titleOrder != NULL)
366
            {
367
                if (isset($this->order[$titleOrder]))
368
                {
369
                    if ($this->order[$titleOrder] == 'ASC')
370
                    {
371
                        $titleOrder.='DESC';
372
                    }
373
                    else
374
                    {
375
                        $titleOrder.='ASC';
376
                    }
377
                }
378
                else 
379
                {
380
                    $titleOrder.='ASC';
381
                }
382
                $actionURL = $this->getCurrentURLAndQS('order').'o='.$titleOrder;
383
                $html .= '<th><a href="'.$actionURL.'">' . $values . '</a></th>';
384
            }
385
            else 
386
            {
387
                $html .= '<th>' . $values . '</th>';
388
            }          
389
        }
390
        $html .= "</tr>\n</thead>\n";
391
        return $html;
392
    }
393
    
394
    public function renderLine( $value)
395
    {
396
        $html = '';
397
        $titleNames = array_keys($this->titles);
398
        foreach ($titleNames as $name )
399
        {
400
            $html .= '<td>';
401
            $html .= $value->$name;
402
            $html .= "</td>\n";
403
        }
404
        return $html;
405
    }
406
    
407
    public function renderTable(array $values)
408
    {
409
       $html = '<tbody id="obj_table_body">';
410
       foreach($values as $value)
411
       {
412
           $html .= "<tr>\n";
413
           $html .= $this->renderLine($value);
414
           $html .= "</tr>\n";
415
       }
416
       $html .= '</tbody>';
417
       return $html;
418
    }
419
    
420
    public function render()
421
    {
422
        $html = '';
423
        
424
        
425
        $values = $this->fullQuery();
426
        
427
        $html.="<table class='simple common-table table-row-selectable'>\n";
428
        
429
        $html .= $this->renderTitles();
430
        $html .= $this->renderTable($values);
431
        $html .= '</table>'; 
432
        
433
434
        return $html;
435
    }
436
    
437
}