Completed
Push — master ( 8849ee...a1b70f )
by Andreas
24:35
created

grid::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 2
dl 0
loc 6
ccs 5
cts 5
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package midcom.grid
4
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
6
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
7
 */
8
9
namespace midcom\grid;
10
11
use midcom;
12
use midcom_error;
13
14
/**
15
 * Helper class for jqgrid widgets
16
 *
17
 * @package midcom.grid
18
 */
19
class grid
20
{
21
    /**
22
     * The grid's ID
23
     *
24
     * @var string
25
     */
26
    private $_identifier;
27
28
    /**
29
     * The grid's options (converted for use in JS constructor)
30
     *
31
     * @var array
32
     */
33
    private $_options = [];
34
35
    /**
36
     * The grid's options as passed in PHP
37
     *
38
     * @var array
39
     */
40
    private $_raw_options = [];
41
42
    /**
43
     * The grid's columns
44
     *
45
     * They have the following structure
46
     *
47
     * 'key' => array
48
     * (
49
     *     'label' => "Some label",
50
     *     'options' => 'javascript option string'
51
     * )
52
     *
53
     * @var array
54
     */
55
    private $_columns = [];
56
57
    /**
58
     * Flag that tracks if JS/CSS files have already been added
59
     *
60
     * @var boolean
61
     */
62
    private static $_head_elements_added = false;
63
64
    /**
65
     * Data for the table footer
66
     *
67
     * @var array
68
     */
69
    private $_footer_data = [];
70
71
    /**
72
     * Should formatters be applied to footer row
73
     *
74
     * @var boolean
75
     */
76
    private $format_footer = true;
77
78
    /**
79
     * The data provider, if any
80
     *
81
     * @var provider
82
     */
83
    private $_provider;
84
85
    /**
86
     * Javascript code that should be prepended to the widget constructor
87
     *
88
     * @var string
89
     */
90
    private $_prepend_js;
91
92
    /**
93
     * Adds the necessary javascript & css files for jqgrid
94
     */
95 44
    public static function add_head_elements()
96
    {
97 44
        if (self::$_head_elements_added) {
98 43
            return;
99
        }
100 1
        $version = '4.15.4';
101 1
        $jqgrid_path = '/midcom.grid/jqGrid-' . $version . '/';
102
103 1
        $head = midcom::get()->head;
104 1
        $head->enable_jquery_ui(['button', 'mouse', 'resizable']);
105
106
        //needed js/css-files for jqgrid
107 1
        $lang = "en";
108 1
        $language = midcom::get()->i18n->get_current_language();
109 1
        if (file_exists(MIDCOM_STATIC_ROOT . $jqgrid_path . 'i18n/grid.locale-' . $language . '.js')) {
110 1
            $lang = $language;
111
        }
112 1
        $head->add_jsfile(MIDCOM_STATIC_URL . $jqgrid_path . 'i18n/grid.locale-'. $lang . '.js');
113 1
        $head->add_jsfile(MIDCOM_STATIC_URL . $jqgrid_path . 'jquery.jqgrid.min.js');
114
115 1
        \org_openpsa_widgets_ui::add_head_elements();
116 1
        $head->add_jsfile(MIDCOM_STATIC_URL . '/midcom.grid/jqGrid.custom.js');
117
118 1
        $head->add_stylesheet(MIDCOM_STATIC_URL . $jqgrid_path . 'ui.jqgrid.min.css');
119 1
        $head->add_stylesheet(MIDCOM_STATIC_URL . "/stock-icons/font-awesome-4.7.0/css/font-awesome.min.css");
120 1
        $head->add_stylesheet(MIDCOM_STATIC_URL . '/midcom.grid/jqGrid.custom.css');
121 1
        self::$_head_elements_added = true;
122 1
    }
123
124
    /**
125
     * Constructor. Add head elements when necessary and the ID column
126
     *
127
     * @param string $identifier The grid's ID
128
     * @param string $datatype The grid's data type
129
     */
130 36
    public function __construct($identifier, $datatype)
131
    {
132 36
        $this->_identifier = $identifier;
133 36
        $this->set_column('id', 'id', 'hidden:true, key:true');
134 36
        $this->set_option('datatype', $datatype);
135 36
        self::add_head_elements();
136 36
    }
137
138 32
    public function set_provider(provider $provider)
139
    {
140 32
        $this->_provider = $provider;
141 32
    }
142
143 3
    public function get_provider()
144
    {
145 3
        return $this->_provider;
146
    }
147
148
    /**
149
     * Returns the grid's ID
150
     *
151
     * @return string
152
     */
153 31
    public function get_identifier()
154
    {
155 31
        return $this->_identifier;
156
    }
157
158
    /**
159
     * Set an option
160
     *
161
     * @param string $key The option's name
162
     * @param mixed $value The option's value
163
     * @param boolean $autoquote_string Should string values be quoted
164
     */
165 36
    public function set_option($key, $value, $autoquote_string = true)
166
    {
167 36
        $this->_raw_options[$key] = $value;
168 36
        if (   $autoquote_string
169 36
            && is_string($value)) {
170 36
            $value = '"' . str_replace('"', '\\"', $value) . '"';
171 32
        } elseif ($value === true) {
172 31
            $value = 'true';
173 32
        } elseif ($value === false) {
174
            $value = 'false';
175 32
        } elseif (is_array($value)) {
176 19
            $value = json_encode($value);
177
        }
178 36
        $this->_options[$key] = $value;
179 36
        return $this;
180
    }
181
182 26
    public function get_option($key)
183
    {
184 26
        if (empty($this->_raw_options[$key])) {
185 25
            return null;
186
        }
187 13
        return $this->_raw_options[$key];
188
    }
189
190
    /**
191
     * Set a column
192
     *
193
     * @param string $name The column's name
194
     * @param string $label The column's label
195
     * @param string $options The column's options
196
     * @param array $selectdata Should the column have a separate index, if so, which sort type
197
     */
198 10
    public function set_select_column($name, $label, $options, array $selectdata)
199
    {
200 10
        $selectstring = implode(';', array_map(
201 10
            function ($key, $value) {
202 10
                return $key . ':' . $value;
203 10
            },
204
            array_keys($selectdata),
205
            $selectdata
206
        ));
207
208 10
        if ($options !== '') {
209 8
            $options .= ', ';
210
        }
211 10
        $options .= 'stype: "select", searchoptions: {sopt: ["eq"], value: ":;' . $selectstring . '"}';
212 10
        $options .= ', edittype:"select", formatter:"select", editoptions:{value:"' . $selectstring . '"}';
213
214 10
        return $this->set_column($name, $label, $options);
215
    }
216
217
    /**
218
     * Set a column
219
     *
220
     * @param string $name The column's name
221
     * @param string $label The column's label
222
     * @param string $options The column's options
223
     * @param string $separate_index Should the column have a separate index, if so, which sort type
224
     */
225 36
    public function set_column($name, $label, $options = '', $separate_index = false)
226
    {
227 36
        if (empty($name)) {
228
            throw new midcom_error('Invalid column name ' . $name);
229
        }
230 36
        $this->_columns[$name] = [
231 36
            'label' => $label,
232 36
            'options' => $options,
233 36
            'separate_index' => $separate_index
234
        ];
235 36
        return $this;
236
    }
237
238 2
    public function add_pager($rows_per_page = 30)
239
    {
240 2
        $this->set_option('pager', '#p_' . $this->_identifier);
241 2
        $this->set_option('rowNum', $rows_per_page);
242 2
        return $this;
243
    }
244
245
    /**
246
     * Removes a column
247
     *
248
     * @param string $name The column's name
249
     */
250
    public function remove_column($name)
251
    {
252
        if (   empty($name)
253
            || !array_key_exists($name, $this->_columns)) {
254
            throw new midcom_error('Invalid column name ' . $name);
255
        }
256
        if ($this->_columns[$name]['separate_index']) {
257
            unset($this->_columns[$name . '_index']);
258
        }
259
        unset($this->_columns[$name]);
260
    }
261
262
    /**
263
     * Set the grid's footer data
264
     *
265
     * @param mixed $data The data to set as array or the column name
266
     * @param mixed $value The value, if setting individual columns
267
     * @param boolean $formatted Should formatters be applied to footer data
268
     */
269 17
    public function set_footer_data($data, $value = null, $formatted = true)
270
    {
271 17
        if (null == $value) {
272 17
            $this->_footer_data = $data;
273
        } else {
274
            $this->_footer_data[$data] = $value;
275
        }
276 17
        $this->format_footer = $formatted;
277 17
        $this->set_option('footerrow', true);
278 17
    }
279
280
    /**
281
     * Add Javascript code that should be run before the widget constructor
282
     *
283
     * @param string $string
284
     */
285 25
    public function prepend_js($string)
286
    {
287 25
        $this->_prepend_js .= $string . "\n";
288 25
    }
289
290
    /**
291
     * Renders the grid as HTML
292
     */
293 32
    public function render($entries = false)
294
    {
295 32
        if (is_array($entries)) {
296 10
            if (null !== $this->_provider) {
297 6
                $this->_provider->set_rows($entries);
298
            } else {
299 10
                $this->_provider = new provider($entries, $this->get_option('datatype'));
300 10
                $this->_provider->set_grid($this);
301
            }
302
        }
303 32
        echo $this->__toString();
304 32
    }
305
306 33
    public function __toString()
307
    {
308 33
        if ($this->_provider) {
309 31
            $this->_provider->setup_grid();
310
        }
311
312 33
        $string = '<table id="' . $this->_identifier . '"></table>';
313 33
        $string .= '<div id="p_' . $this->_identifier . '"></div>';
314 33
        $string .= '<script type="text/javascript">//<![CDATA[' . "\n";
315 33
        $string .= $this->_prepend_js;
316 33
        $string .= 'midcom_grid_helper.setup_grid("' . $this->_identifier . '", {';
317
318 33
        $colnames = [];
319 33
        foreach ($this->_columns as $name => $column) {
320 33
            if ($column['separate_index']) {
321 31
                $colnames[] = 'index_' . $name;
322
            }
323 33
            $colnames[] = $column['label'];
324
        }
325 33
        $string .= "\ncolNames: " . json_encode($colnames) . ",\n";
326
327 33
        $string .= $this->_render_colmodel();
328
329 33
        $total_options = count($this->_options);
330 33
        $i = 0;
331 33
        foreach ($this->_options as $name => $value) {
332 33
            $string .= $name . ': ' . $value;
333 33
            if (++$i < $total_options) {
334 32
                $string .= ',';
335
            }
336 33
            $string .= "\n";
337
        }
338 33
        $string .= "});\n";
339
340 33
        if ($this->_footer_data) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->_footer_data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
341 17
            $format = $this->format_footer ? 'true' : 'false';
342 17
            $string .= 'jQuery("#' . $this->_identifier . '").jqGrid("footerData", "set", ' . json_encode($this->_footer_data) . ", " . $format . ");\n";
343
        }
344
345 33
        $string .= '//]]></script>';
346 33
        return $string;
347
    }
348
349 33
    private function _render_colmodel()
350
    {
351 33
        $string = "colModel: [\n";
352 33
        $total_columns = count($this->_columns);
353 33
        $i = 0;
354 33
        foreach ($this->_columns as $name => $column) {
355 33
            if ($column['separate_index']) {
356 31
                $string .= '{name: "index_' . $name . '", index: "index_' . $name . '", ';
357 31
                $string .= 'sorttype: "' . $column['separate_index'] . '", hidden: true}' . ",\n";
358
            }
359
360 33
            $string .= '{name: "' . $name . '", ';
361 33
            if ($column['separate_index']) {
362 31
                $string .= 'index: "index_' . $name . '"';
363
            } else {
364 33
                $string .= 'index: "' . $name . '"';
365
            }
366 33
            if (!empty($column['options'])) {
367 33
                $string .= ', ' . $column['options'];
368
            }
369 33
            $string .= '}';
370 33
            if (++$i < $total_columns) {
371 33
                $string .= ",\n";
372
            }
373
        }
374 33
        $string .= "\n],\n";
375 33
        return $string;
376
    }
377
}
378