Passed
Push — master ( a13310...b93b90 )
by Plamen
01:25
created

table.php (5 issues)

1
<?php
2
3
/** Note: table::prepare() - call must come before `headers_sent()`;
4
 *     1. Create (initial setup):
5
 *        <code>table::create('tableId', 'sortByDbCol', 'sortDirection');</code>
6
 *     1.1. Set columns to be displayed: <code>
7
 *          table::$cols[] = ['innerHtml', 'dbColumn|Name',
8
 *                                      ['width'=>'?px','sort'=>false]];</code>
9
 *     2. Execute (data query)
10
 *        <code>table::execute(sqlQuery);</code>
11
 *     2.1. Alter loaded data, before table load <code>
12
 *          foreach(table::$data as $r => &$cells){
13
 *              $cells['id'] = $cells['id']==3 ?
14
 *                              [$cells['id'] ,['class'=>'red']] : $cells['id'];
15
 *          }</code>
16
 *     3. Loads the markup, or json data (on sort/page/export etc. actions).
17
 *        <code>table::load();</code> */
18
class table extends table_getter
19
{
20
    /** @param string class name, where $helper::prepare() is expected */
21
    public static $helper_class;
22
    /** @param closure to MySql select function (example: db::select()) */
23
    public static $select;
24
25
    /** #1. Create (setup)
26
     * @param string $items - The items name
27
     * @param string $orderBy - a db column name
28
     * @param string $orderDir - (Default: self::DEFAULT_SORT_ORDER)
29
     * @param int $paging - Rows per page */
30
    public static function create($items, $orderBy, $orderDir = 'asc', $paging = 10)
31
    {
32
        self::reset((self::$t['items'] = $items));
33
        self::prepare(true);
34
        self::$t['order']['col'] = $orderBy;
35
        $dir = strtolower($orderDir);
36
        self::$t['order']['dir'] = in_array($dir, ['asc', 'desc']) ? $dir :
37
                die('Invalid orderDir(Asc/Desc): ' . $orderDir);
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
38
        self::$t['paging'] = ($p = abs($paging)) > 10 ? $p :
39
                die('Invalid paging(>10): ' . $paging);
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
40
    }
41
42
    /** #2. Execute (queries)
43
     * @param string $q - query for the table data;
44
     * @param (null)|string $qTotal - simple version of $sql if applicable
45
     * (used only for Total count in the table footer).<br>
46
     * Example: <pre>$sql = 'SELECT `id`, ... FROM `table` WHERE ...'</pre>
47
     * For query to many thousands results, will be faster to have:
48
     * <pre>$sqlTotals = 'SELECT `id` FROM `table` WHERE ...'</pre> */
49
    public static function execute($q, $qTotal = null)
50
    {
51
        self::$t['order']['col'] = self::requestOrderCol();
52
        self::$t['order']['dir'] = self::requestOrderDir();
53
        self::$t['page'] = self::requestPage();
54
        self::$export = self::requestExport();
55
56
        $filter = self::requestFilter();
57
        $order = [self::$t['order']['col'] => self::$t['order']['dir']];
58
        $offset = (self::$t['page'] - 1) * self::$t['paging'];
59
        $limit = [$offset, self::$t['paging']];
60
        self::$t['q'] = self::q($q, $filter, $order, $limit, true);
0 ignored issues
show
It seems like $filter can also be of type false; however, parameter $cond of table_getter::q() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

60
        self::$t['q'] = self::q($q, /** @scrutinizer ignore-type */ $filter, $order, $limit, true);
Loading history...
61
62
        $qAll = isset($qTotal) && ! $filter ? $qTotal : $q;
63
        $orderAll = ! self::$export ? [] : $order;
64
        self::$t['qAll'] = self::q($qAll, $filter, $orderAll, 0, true);
65
66
        $query = ! self::$export ? self::$t['q'] : self::$t['qAll'];
67
68
        try {
69
            self::$data = self::select($query);
70
        } catch (Exception $e) {
71
            die('ERROR (query in the table): ' . "\n$q\n" . $e -> getMessage());
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
72
        }
73
    }
74
75
    /** #3. Loads output (html, json or csv file) */
76
    public static function load()
77
    {
78
        if (self::$pageExt !== 'json') {
79
            echo parent::load();
80
        } else {
81
            ob_get_clean();
82
            $tableId = filter_input(INPUT_GET, 'table-id') ?: null;
83
            if ($tableId === self::$t['items'] . '-table') {
84
                if ( ! self::$export) {
85
                    header('Content-Type: application/json');
86
                    $jsonArr = ['body' => self::jsonGetBodyData(),
87
                        'footer' => self::jsonGetFooterData()];
88
                    die(json_encode($jsonArr));
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
89
                } else {
90
                    return self::exportData();
91
                }
92
            }
93
        }
94
    }
95
96
    /** Adds needed JavaScript and CSS into the page header, it has to be
97
     * included before "headers_sent()"
98
     * @param str|bool $setOrCheck - uses helper class to verify own load */
99
    public static function prepare($setOrCheck = false)
100
    {
101
        //@see  http://php.net/manual/es/function.filter-input.php#77307
102
        $uri = filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_URL) ?:
103
                filter_var($_SERVER['REQUEST_URI'], FILTER_SANITIZE_URL);
104
105
        $extension = pathinfo(strtok($uri, '?'), PATHINFO_EXTENSION);
106
107
        self::$t['slug'] = pathinfo($uri, PATHINFO_BASENAME);
108
        self::$pageExt = strtolower($extension);
109
110
        if (self::$helper_class::prepare(__METHOD__, $setOrCheck) !== true) {
111
            if (self::$pageExt === 'json' && ! isset(self::$t['prepared'])) {
112
                ob_start();
113
                self::$t['prepared'] = true;
114
            }
115
        }
116
    }
117
}
118