Passed
Push — master ( af185e...b32849 )
by Plamen
01:30
created
Labels
Severity
1
<?php
2
3
/**
4
 * Note: table::prepare() - call must come before `headers_sent()`;
5
 *     1. Create (initial setup):
6
 *        <code>table::create('tableId', 'sortByDbCol', 'sortDirection');</code>
7
 *     1.1. Set columns to be displayed: <code>
8
 *          table::$cols[] = ['innerHtml', 'dbColumn|Name',
9
 *                                      ['width'=>'?px','sort'=>false]];</code>
10
 *     2. Execute (data query)
11
 *        <code>table::execute(sqlQuery);</code>
12
 *     2.1. Alter loaded data, before table load <code>
13
 *          foreach(table::$data as $r => &$cells){
14
 *              $cells['id'] = $cells['id']==3 ?
15
 *                              [$cells['id'] ,['class'=>'red']] : $cells['id'];
16
 *          }</code>
17
 *     3. Loads the markup, or json data (on sort/page/export etc. actions).
18
 *        <code>table::load();</code>
19
 */
20
class Table extends Thead
21
{
22
23
    use trait_request;
24
25
    /**
26
     * Adds needed JavaScript and CSS into the page header, it has to be
27
     * included before "headers_sent()".
28
     *
29
     * @param string|bool $setOrCheck - uses helper class to verify own load */
30
    public static function prepare($setOrCheck = false)
31
    {
32
        //@see  http://php.net/manual/es/function.filter-input.php#77307
33
        $uri = filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_URL) ?:
34
            filter_var($_SERVER['REQUEST_URI'], FILTER_SANITIZE_URL);
35
36
        $extension = pathinfo(strtok($uri, '?'), PATHINFO_EXTENSION);
37
38
        self::$t['slug'] = pathinfo($uri, PATHINFO_BASENAME);
39
        self::$pageExt = strtolower($extension);
40
41
        if (self::$helperClass::prepare(__METHOD__, $setOrCheck) !== true) {
42
            if (self::$pageExt === 'json' && !isset(self::$t['prepared'])) {
43
                ob_start();
44
                self::$t['prepared'] = true;
45
            }
46
        }
47
    }
48
49
    /**
50
     * #1. Create (setup)
51
     * @param string $items - The items name
52
     * @param string $orderBy - a db column name
53
     * @param string $orderDir - (Default: self::DEFAULT_SORT_ORDER)
54
     * @param int $paging - Rows per page */
55
    public static function create(
56
        $items,
57
        $orderBy,
58
        $orderDir = 'asc',
59
        $paging = 10
60
    )
61
    {
62
        self::reset((self::$t['items'] = (string) $items));
0 ignored issues
show
self::t['items'] = (string)$items of type string is incompatible with the type strings expected by parameter $items of Tfoot::reset(). ( Ignorable by Annotation )

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

62
        self::reset(/** @scrutinizer ignore-type */ (self::$t['items'] = (string) $items));
Loading history...
63
        self::prepare(true);
64
        self::$t['order']['col'] = $orderBy;
65
        $dir = strtolower($orderDir);
66
        self::$t['order']['dir'] = in_array($dir, ['asc', 'desc']) ?
67
                $dir : self::error('Invalid orderDir (Asc/Desc): ' . $orderDir);
68
        self::$t['paging'] = ($num = abs($paging)) > 10 ?
69
                $num : self::error('Invalid paging (>10): ' . $paging);
70
    }
71
72
    /**
73
     * #2. Execute (queries)
74
     * @param string        $query - query for the table data;
75
     * @param (null)|string $qTotal - simple version of $sql if applicable
76
     *                          (used only for Total count in the table footer).
77
     *
78
     * Example: <pre>$sql = 'SELECT `id`, ... FROM `table` WHERE ...'</pre>
79
     * For query to many thousands results, will be faster to have:
80
     * <pre>$sqlTotals = 'SELECT `id` FROM `table` WHERE ...'</pre> */
81
    public static function execute($query, $qTotal = null)
82
    {
83
        self::$t = self::request(self::$export);
84
85
        $order = [self::$t['order']['col'] => self::$t['order']['dir']];
86
        $offset = (self::$t['page'] - 1) * self::$t['paging'];
87
        $limit = [$offset, self::$t['paging']];
88
        self::$t['q'] = self::query($query, self::$t['filter'], $order, $limit, true);
89
90
        $qAll = isset($qTotal) && !self::$t['filter'] ? $qTotal : $query;
91
        $ordAll = !self::$export ? [] : $order;
92
        self::$t['qAll'] = self::query($qAll, self::$t['filter'], $ordAll, 0, true);
93
94
        $query = !self::$export ? self::$t['q'] : self::$t['qAll'];
95
96
        try {
97
            self::$data = self::select($query);
98
        } catch (Exception $e) {
99
            self::error('ERROR: ' . $query . '<br />' . $e->getMessage());
100
        }
101
    }
102
103
    /**
104
     * #3. Loads output (HTML, JSON or CSV file) */
105
    public static function load()
106
    {
107
        if (self::$pageExt !== 'json') {
108
            echo parent::load();
109
        } else {
110
            $tableId = filter_input(INPUT_GET, 'table-id') ?: null;
111
            if ($tableId === self::$t['items'] . '-table') {
112
                ob_get_clean();
113
                ob_start("ob_gzhandler");
114
                if (!self::$export) {
115
                    header('Content-Type: application/json');
116
                    $jsonArr = ['body' => self::jsonTbody(),
117
                        'footer' => self::jsonTfoot()];
118
                    echo json_encode($jsonArr);
119
                } else {
120
                    self::export();
121
                }
122
                ob_end_flush();
123
            }
124
        }
125
    }
126
}
127