Passed
Push — master ( 1d8afe...b3ce84 )
by Patrick
02:10
created

TrapDirectorTable::initGrouping()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 4
rs 10
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
    /*************** Grouping ************/
51
    protected $grouppingActive=false;
52
    
53
    protected $groupingColumn='';
54
    
55
    protected $groupingVal='';
56
    
57
    protected $groupingColSpan=1;
58
    
59
    function __construct(array $table,array $titles, array $columns, array $columnNames, $dbConn , $view, $urlPath)
60
    {
61
        $this->table = $table;
62
        $this->titles = $titles;
63
        $this->content = $columns;
64
        $this->columnNames = $columnNames;
65
        $this->dbConn = $dbConn;
66
        
67
        $this->view = $view;
68
        $this->urlPath = $urlPath;
69
        
70
        return $this;
71
    }
72
73
    
74
    /************** GET variables and URLs *************/
75
    public function getParams(array $getVars)
76
    {
77
        $this->getFilterQuery($getVars);
78
        $this->getPagingQuery($getVars);
79
        $this->getOrderQuery($getVars);
80
    }
81
    
82
    public function getCurrentURL()
83
    {
84
        return '?';
85
    }
86
    
87
    protected function getCurrentURLAndQS(string $caller)
88
    {
89
        $actionURL = $this->getCurrentURL() . '?' ;
90
        $QSList=array();
91
        if ($caller != 'filter' && $this->curFilterQuery() != '')
92
            array_push($QSList , $this->curFilterQuery());
93
        
94
        if ($caller != 'paging' && $caller != 'filter' && $this->curPagingQuery() != '')
95
            array_push($QSList , $this->curPagingQuery());
96
 
97
        if ($caller != 'order' && $this->curOrderQuery() != '')
98
            array_push($QSList , $this->curOrderQuery());
99
        
100
        if (count($QSList) != 0)
101
            $actionURL .=  implode('&', $QSList) . '&';
102
        
103
        return $actionURL;
104
    }
105
    
106
    /************* DB queries ******************/
107
    /**
108
     * Get base query in $this->query
109
     * @return  TrapDirectorTable
110
     */
111
    public function getBaseQuery()
112
    {
113
        $this->query = $this->dbConn->select();
114
        $this->query = $this->query->from(
115
            $this->table,
116
            $this->content
117
            );
118
        
119
        return $this;
120
    }
121
    
122
    public function fullQuery()
123
    {
124
        $this->getBaseQuery()
125
        ->applyFilter()
126
        ->applyPaging()
127
        ->applyOrder();
128
        
129
        return $this->dbConn->fetchAll($this->query);
130
        //return $this->query->fetchAll();
131
    }
132
    
133
    
134
    /**************** Filtering ******************/
135
    
136
    public function applyFilter()
137
    {
138
        if ($this->filterString == '' || count($this->filterColumn) == 0)
139
        {
140
            return $this;
141
        }
142
        $filter='';
143
        foreach ($this->filterColumn as $column)
144
        {
145
            if ($filter != "") $filter.=' OR ';
146
            //$filter .= "'" . $column . "' LIKE '%" . $this->filterString. "%'";
147
            $filter .= $column  . " LIKE '%" . $this->filterString. "%'";
148
        }
149
        //echo $filter;
150
        
151
        $this->query=$this->query->where($filter);
152
153
        return $this;
154
    }
155
156
    public function setFilter(string $filter, array $filterCol)
157
    {
158
        $this->filterString = $filter;
159
        $this->filterColumn = $filterCol;
160
        return $this;
161
    }
162
   
163
    public function renderFilter()
164
    {
165
        
166
        $html=' <form id="genfilter" name="mainFilterGen"
167
			enctype="application/x-www-form-urlencoded"
168
			action="'.$this->getCurrentURLAndQS('filter').'"
169
			method="get">';
170
        $html.='<input type="text" name="f" title="Search is simple! Try to combine multiple words"
171
	placeholder="Search..."  value="'.$this->filterQuery.'">';
172
173
        $html.='</form>';
174
        return $html;
175
    }
176
 
177
    public function getFilterQuery(array $getVars)
178
    {
179
        if (isset($getVars['f']))
180
        {
181
            $this->filterQuery = $getVars['f'];
182
            $this->setFilter(html_entity_decode($getVars['f']), $this->columnNames);
183
        }
184
    }
185
    
186
    protected function curFilterQuery()
187
    {
188
        if ($this->filterQuery == '') return '';
189
        return 'f='.$this->filterQuery;
190
    }
191
    
192
    /***************** Ordering ********************/
193
    
194
    public function applyOrder()
195
    {
196
        if (count($this->order) == 0)
197
        {
198
            return $this;
199
        }
200
        $orderSQL='';
201
        foreach ($this->order as $column => $direction)
202
        {
203
            if ($orderSQL != "") $orderSQL.=',';
204
            
205
            $orderSQL .= $column . ' ' . $direction;
206
        }
207
        $this->query = $this->query->order($orderSQL);
208
        
209
        return $this;
210
    }
211
    
212
    public function setOrder(array $order)
213
    {
214
        $this->order = $order;
215
        return $this;
216
    }
217
218
    public function isOrderSet()
219
    {
220
        if (count($this->order == 0)) return FALSE;
0 ignored issues
show
Bug introduced by
$this->order == 0 of type boolean is incompatible with the type Countable|array expected by parameter $var of count(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

220
        if (count(/** @scrutinizer ignore-type */ $this->order == 0)) return FALSE;
Loading history...
221
        return TRUE;
222
    }
223
    
224
    public function getOrderQuery(array $getVars)
225
    {
226
        if (isset($getVars['o']))
227
        {
228
            $this->orderQuery = $getVars['o'];
229
            $match = array();
230
            if (preg_match('/(.*)(ASC|DESC)$/', $this->orderQuery , $match))
231
            {
232
                $orderArray=array($match[1] => $match[2]);
233
                echo "$match[1] => $match[2]";
234
                $this->setOrder($orderArray);
235
            }
236
        }
237
    }
238
    
239
    protected function curOrderQuery()
240
    {
241
        if ($this->orderQuery == '') return '';
242
        return 'o='.$this->orderQuery;
243
    }
244
    
245
    /*****************  Paging and counting *********/
246
    
247
    public function countQuery()
248
    {
249
        $this->query = $this->dbConn->select();
250
        $this->query = $this->query
251
            ->from(
252
                $this->table,
253
                array('COUNT(*)')
254
                );
255
        $this->applyFilter();                   
256
    }
257
    
258
    public function count()
259
    {
260
        $this->countQuery();
261
        return $this->dbConn->fetchOne($this->query);
262
    }
263
    
264
    public function setMaxPerPage(int $max)
265
    {
266
        $this->maxPerPage = $max;
267
    }
268
    
269
    protected function getPagingQuery(array $getVars)
270
    {
271
        if (isset($getVars['page']))
272
        {
273
            $this->currentPage = $getVars['page'];
274
        }
275
    }
276
277
    protected function curPagingQuery()
278
    {
279
        if ($this->currentPage == '') return '';
280
        return 'page='.$this->currentPage;
281
    }
282
    
283
    public function renderPagingHeader()
284
    {
285
        $count = $this->count();
286
        if ($count <= $this->maxPerPage )
287
        {
288
            return  'count : ' . $this->count() . '<br>';
289
        }
290
        
291
        if ($this->currentPage == 0) $this->currentPage = 1;
292
        
293
        $numPages = intdiv($count , $this->maxPerPage);
294
        if ($count % $this->maxPerPage != 0 ) $numPages++;
295
        
296
        $html = '<div class="pagination-control" role="navigation">';
297
        $html .= '<ul class="nav tab-nav">';
298
        if ($this->currentPage <=1)
299
        {
300
            $html .= '
301
                <li class="nav-item disabled" aria-hidden="true">
302
                    <span class="previous-page">
303
                            <span class="sr-only">Previous page</span>
304
                            <i aria-hidden="true" class="icon-angle-double-left"></i>            
305
                     </span>
306
                </li>
307
               ';
308
        }
309
        else 
310
        {
311
            $html .= '
312
                <li class="nav-item">
313
                    <a href="'. $this->getCurrentURLAndQS('paging') .'&page='. ($this->currentPage - 1 ).'" class="previous-page" >
314
                            <i aria-hidden="true" class="icon-angle-double-left"></i>            
315
                     </a>
316
                </li>
317
            ';
318
        }
319
        
320
        for ($i=1; $i <= $numPages ; $i++)
321
        {
322
            $active = ($this->currentPage == $i) ? 'active' : '';
323
            $first = ($i-1)*$this->maxPerPage+1;
324
            $last = $i * $this->maxPerPage;
325
            if ($last > $count) $last = $count;
326
            $display = 'Show rows '. $first . ' to '. $last .' of '. $count;
327
            $html .= '<li class="' . $active . ' nav-item">
328
                    <a href="'. $this->getCurrentURLAndQS('paging') .'&page='. $i .'" title="' . $display . '" aria-label="' . $display . '">
329
                    '.$i.'                
330
                    </a>
331
                </li>';
332
        }
333
        
334
        if ($this->currentPage == $numPages)
335
        {
336
            $html .= '
337
                <li class="nav-item disabled" aria-hidden="true">
338
                    <span class="previous-page">
339
                            <span class="sr-only">Previous page</span>
340
                            <i aria-hidden="true" class="icon-angle-double-right"></i>
341
                     </span>
342
                </li>
343
               ';
344
        }
345
        else
346
        {
347
            $html .= '
348
                <li class="nav-item">
349
                    <a href="'. $this->getCurrentURLAndQS('paging') .'&page='. ($this->currentPage + 1 ).'" class="next-page">
350
                            <i aria-hidden="true" class="icon-angle-double-right"></i>
351
                     </a>
352
                </li>
353
            ';
354
        }
355
        
356
        $html .= '</ul> </div>';
357
        
358
        return $html;
359
    }
360
    
361
    public function applyPaging()
362
    {
363
        $this->query->limitPage($this->currentPage,$this->maxPerPage);
364
        return $this;
365
    }
366
    
367
    /*****************  Grouping ****************/
368
    
369
    public function setGrouping($columnDBName)
370
    {
371
        $this->groupingColumn = $columnDBName;
372
        $this->grouppingActive = TRUE;
373
    }
374
    
375
    public function initGrouping()
376
    {
377
        $this->groupingVal = '';
378
        $this->groupingColSpan = count($this->titles);
379
    }
380
    
381
    public function groupingPrintData( $value)
382
    {
383
        $html = "$value";
384
        return $html;
385
    }
386
    
387
    public function groupingNextLine( $values)
388
    {
389
        if ($this->grouppingActive === FALSE) return '';
390
        
391
        $dbcol = $this->groupingColumn;
392
        if ($this->groupingVal == '' || $this->groupingVal != $values->$dbcol )
393
        {
394
            $this->groupingVal = $values->$dbcol;
395
            $html = '<tr><th colspan="'. $this->groupingColSpan .'">'. $this->groupingPrintData($this->groupingVal) .'</th></tr>';
396
            return $html;
397
        }
398
        return '';
399
        
400
    }
401
    
402
    /*************** Rendering *************************/
403
    
404
    public function titleOrder($name)
405
    {
406
        return $this->content[$name];
407
    }
408
    
409
    public function renderTitles()
410
    {
411
        $html = "<thead>\n<tr>\n";
412
        foreach ($this->titles as $name => $values)
413
        {
414
            $titleOrder = $this->titleOrder($name);
415
            if ($titleOrder != NULL)
416
            {
417
                if (isset($this->order[$titleOrder]))
418
                {
419
                    if ($this->order[$titleOrder] == 'ASC')
420
                    {
421
                        $titleOrder.='DESC';
422
                    }
423
                    else
424
                    {
425
                        $titleOrder.='ASC';
426
                    }
427
                }
428
                else 
429
                {
430
                    $titleOrder.='ASC';
431
                }
432
                $actionURL = $this->getCurrentURLAndQS('order').'o='.$titleOrder;
433
                $html .= '<th><a href="'.$actionURL.'">' . $values . '</a></th>';
434
            }
435
            else 
436
            {
437
                $html .= '<th>' . $values . '</th>';
438
            }          
439
        }
440
        $html .= "</tr>\n</thead>\n";
441
        return $html;
442
    }
443
    
444
    public function renderLine( $value)
445
    {
446
        $html = '';
447
        $titleNames = array_keys($this->titles);
448
        foreach ($titleNames as $name )
449
        {
450
            $html .= '<td>';
451
            $html .= $value->$name;
452
            $html .= "</td>\n";
453
        }
454
        return $html;
455
    }
456
    
457
    public function renderTable(array $values)
458
    {
459
       $html = '<tbody id="obj_table_body">';
460
       foreach($values as $value)
461
       {
462
           $html .= $this->groupingNextLine($value);
463
           
464
           $html .= "<tr>\n";
465
           $html .= $this->renderLine($value);
466
           $html .= "</tr>\n";
467
       }
468
       $html .= '</tbody>';
469
       return $html;
470
    }
471
    
472
    public function render()
473
    {
474
        $html = '';
475
        
476
        
477
        $values = $this->fullQuery();
478
        $this->initGrouping();
479
        
480
        $html.="<table class='simple common-table table-row-selectable'>\n";
481
        
482
        $html .= $this->renderTitles();
483
        $html .= $this->renderTable($values);
484
        $html .= '</table>'; 
485
        
486
487
        return $html;
488
    }
489
    
490
}