Completed
Push — master ( 9de7f6...0376ba )
by Andreas
21:44
created

grid::get_identifier()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
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 38
    public static function add_head_elements()
96
    {
97 38
        if (self::$_head_elements_added) {
98 37
            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 37
    public function __construct($identifier, $datatype)
131
    {
132 37
        $this->_identifier = $identifier;
133 37
        $this->set_column('id', 'id', 'hidden:true, key:true');
134 37
        $this->set_option('datatype', $datatype);
135 37
        self::add_head_elements();
136 37
    }
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 31
    public function get_identifier() : string
152
    {
153 31
        return $this->_identifier;
154
    }
155
156
    /**
157
     * Set an option
158
     *
159
     * @param string $key The option's name
160
     * @param mixed $value The option's value
161
     * @param boolean $autoquote_string Should string values be quoted
162
     */
163 37
    public function set_option($key, $value, $autoquote_string = true) : self
164
    {
165 37
        $this->_raw_options[$key] = $value;
166 37
        if (   $autoquote_string
167 37
            && is_string($value)) {
168 37
            $value = '"' . str_replace('"', '\\"', $value) . '"';
169 33
        } elseif ($value === true) {
170 32
            $value = 'true';
171 33
        } elseif ($value === false) {
172
            $value = 'false';
173 33
        } elseif (is_array($value)) {
174 19
            $value = json_encode($value);
175
        }
176 37
        $this->_options[$key] = $value;
177 37
        return $this;
178
    }
179
180 26
    public function get_option($key)
181
    {
182 26
        if (empty($this->_raw_options[$key])) {
183 25
            return null;
184
        }
185 11
        return $this->_raw_options[$key];
186
    }
187
188
    /**
189
     * Set a column
190
     *
191
     * @param string $name The column's name
192
     * @param string $label The column's label
193
     * @param string $options The column's options
194
     * @param array $selectdata Should the column have a separate index, if so, which sort type
195
     */
196 10
    public function set_select_column($name, $label, $options, array $selectdata) : self
197
    {
198 10
        $selectstring = implode(';', array_map(
199 10
            function ($key, $value) {
200 10
                return $key . ':' . $value;
201 10
            },
202
            array_keys($selectdata),
203
            $selectdata
204
        ));
205
206 10
        if ($options !== '') {
207 8
            $options .= ', ';
208
        }
209 10
        $options .= 'stype: "select", searchoptions: {sopt: ["eq"], value: ":;' . $selectstring . '"}';
210 10
        $options .= ', edittype:"select", formatter:"select", editoptions:{value:"' . $selectstring . '"}';
211
212 10
        return $this->set_column($name, $label, $options);
213
    }
214
215
    /**
216
     * Set a column
217
     *
218
     * @param string $name The column's name
219
     * @param string $label The column's label
220
     * @param string $options The column's options
221
     * @param string $separate_index Should the column have a separate index, if so, which sort type
222
     */
223 37
    public function set_column($name, $label, $options = '', $separate_index = false) : self
224
    {
225 37
        if (empty($name)) {
226
            throw new midcom_error('Invalid column name ' . $name);
227
        }
228 37
        $this->_columns[$name] = [
229 37
            'label' => $label,
230 37
            'options' => $options,
231 37
            'separate_index' => $separate_index
232
        ];
233 37
        return $this;
234
    }
235
236 2
    public function add_pager($rows_per_page = 30) : self
237
    {
238 2
        $this->set_option('pager', '#p_' . $this->_identifier);
239 2
        $this->set_option('rowNum', $rows_per_page);
240 2
        return $this;
241
    }
242
243
    /**
244
     * Removes a column
245
     *
246
     * @param string $name The column's name
247
     */
248
    public function remove_column($name)
249
    {
250
        if (   empty($name)
251
            || !array_key_exists($name, $this->_columns)) {
252
            throw new midcom_error('Invalid column name ' . $name);
253
        }
254
        if ($this->_columns[$name]['separate_index']) {
255
            unset($this->_columns[$name . '_index']);
256
        }
257
        unset($this->_columns[$name]);
258
    }
259
260
    /**
261
     * Set the grid's footer data
262
     *
263
     * @param mixed $data The data to set as array or the column name
264
     * @param mixed $value The value, if setting individual columns
265
     * @param boolean $formatted Should formatters be applied to footer data
266
     */
267 17
    public function set_footer_data($data, $value = null, $formatted = true)
268
    {
269 17
        if (null == $value) {
270 17
            $this->_footer_data = $data;
271
        } else {
272
            $this->_footer_data[$data] = $value;
273
        }
274 17
        $this->format_footer = $formatted;
275 17
        $this->set_option('footerrow', true);
276 17
    }
277
278
    /**
279
     * Add Javascript code that should be run before the widget constructor
280
     *
281
     * @param string $string
282
     */
283 25
    public function prepend_js($string)
284
    {
285 25
        $this->_prepend_js .= $string . "\n";
286 25
    }
287
288
    /**
289
     * Renders the grid as HTML
290
     */
291 33
    public function render($entries = false)
292
    {
293 33
        if (is_array($entries)) {
294 10
            if (null !== $this->_provider) {
295
                $this->_provider->set_rows($entries);
296
            } else {
297 10
                $this->_provider = new provider($entries, $this->get_option('datatype'));
298 10
                $this->_provider->set_grid($this);
299
            }
300
        }
301 33
        echo (string) $this;
302 33
    }
303
304 34
    public function __toString()
305
    {
306 34
        if ($this->_provider) {
307 31
            $this->_provider->setup_grid();
308
        }
309
310 34
        $string = '<table id="' . $this->_identifier . '"></table>';
311 34
        $string .= '<div id="p_' . $this->_identifier . '"></div>';
312 34
        $string .= '<script type="text/javascript">//<![CDATA[' . "\n";
313 34
        $string .= $this->_prepend_js;
314 34
        $string .= 'midcom_grid_helper.setup_grid("' . $this->_identifier . '", {';
315
316 34
        $colnames = [];
317 34
        foreach ($this->_columns as $name => $column) {
318 34
            if ($column['separate_index']) {
319 32
                $colnames[] = 'index_' . $name;
320
            }
321 34
            $colnames[] = $column['label'];
322
        }
323 34
        $string .= "\ncolNames: " . json_encode($colnames) . ",\n";
324
325 34
        $string .= $this->_render_colmodel();
326
327 34
        $total_options = count($this->_options);
328 34
        $i = 0;
329 34
        foreach ($this->_options as $name => $value) {
330 34
            $string .= $name . ': ' . $value;
331 34
            if (++$i < $total_options) {
332 33
                $string .= ',';
333
            }
334 34
            $string .= "\n";
335
        }
336 34
        $string .= "});\n";
337
338 34
        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...
339 17
            $format = $this->format_footer ? 'true' : 'false';
340 17
            $string .= 'jQuery("#' . $this->_identifier . '").jqGrid("footerData", "set", ' . json_encode($this->_footer_data) . ", " . $format . ");\n";
341
        }
342
343 34
        $string .= '//]]></script>';
344 34
        return $string;
345
    }
346
347 34
    private function _render_colmodel() : string
348
    {
349 34
        $string = "colModel: [\n";
350 34
        $total_columns = count($this->_columns);
351 34
        $i = 0;
352 34
        foreach ($this->_columns as $name => $column) {
353 34
            if ($column['separate_index']) {
354 32
                $string .= '{name: "index_' . $name . '", index: "index_' . $name . '", ';
355 32
                $string .= 'sorttype: "' . $column['separate_index'] . '", hidden: true}' . ",\n";
356
            }
357
358 34
            $string .= '{name: "' . $name . '", ';
359 34
            if ($column['separate_index']) {
360 32
                $string .= 'index: "index_' . $name . '"';
361
            } else {
362 34
                $string .= 'index: "' . $name . '"';
363
            }
364 34
            if (!empty($column['options'])) {
365 34
                $string .= ', ' . $column['options'];
366
            }
367 34
            $string .= '}';
368 34
            if (++$i < $total_columns) {
369 34
                $string .= ",\n";
370
            }
371
        }
372 34
        $string .= "\n],\n";
373 34
        return $string;
374
    }
375
}
376