Completed
Push — master ( c3610f...1a80aa )
by Andreas
17:36
created

grid::get_option()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

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