Subversion-Projekte lars-tiefland.ci

Revision

Revision 1257 | Zur aktuellen Revision | Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
68 lars 1
<?php
2
/**
3
 * CodeIgniter
4
 *
5
 * An open source application development framework for PHP
6
 *
7
 * This content is released under the MIT License (MIT)
8
 *
9
 * Copyright (c) 2014 - 2016, British Columbia Institute of Technology
10
 *
11
 * Permission is hereby granted, free of charge, to any person obtaining a copy
12
 * of this software and associated documentation files (the "Software"), to deal
13
 * in the Software without restriction, including without limitation the rights
14
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
 * copies of the Software, and to permit persons to whom the Software is
16
 * furnished to do so, subject to the following conditions:
17
 *
18
 * The above copyright notice and this permission notice shall be included in
19
 * all copies or substantial portions of the Software.
20
 *
21
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
 * THE SOFTWARE.
28
 *
29
 * @package	CodeIgniter
30
 * @author	EllisLab Dev Team
31
 * @copyright	Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
32
 * @copyright	Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/)
33
 * @license	http://opensource.org/licenses/MIT	MIT License
34
 * @link	https://codeigniter.com
35
 * @since	Version 1.3.1
36
 * @filesource
37
 */
38
defined('BASEPATH') OR exit('No direct script access allowed');
39
 
40
/**
41
 * HTML Table Generating Class
42
 *
43
 * Lets you create tables manually or from database result objects, or arrays.
44
 *
45
 * @package		CodeIgniter
46
 * @subpackage	Libraries
47
 * @category	HTML Tables
48
 * @author		EllisLab Dev Team
49
 * @link		https://codeigniter.com/user_guide/libraries/table.html
50
 */
51
class CI_Table {
52
 
53
	/**
54
	 * Data for table rows
55
	 *
56
	 * @var array
57
	 */
58
	public $rows		= array();
59
 
60
	/**
61
	 * Data for table heading
62
	 *
63
	 * @var array
64
	 */
65
	public $heading		= array();
66
 
67
	/**
68
	 * Whether or not to automatically create the table header
69
	 *
70
	 * @var bool
71
	 */
72
	public $auto_heading	= TRUE;
73
 
74
	/**
75
	 * Table caption
76
	 *
77
	 * @var string
78
	 */
79
	public $caption		= NULL;
80
 
81
	/**
82
	 * Table layout template
83
	 *
84
	 * @var array
85
	 */
86
	public $template	= NULL;
87
 
88
	/**
89
	 * Newline setting
90
	 *
91
	 * @var string
92
	 */
93
	public $newline		= "\n";
94
 
95
	/**
96
	 * Contents of empty cells
97
	 *
98
	 * @var string
99
	 */
100
	public $empty_cells	= '';
101
 
102
	/**
103
	 * Callback for custom table layout
104
	 *
105
	 * @var function
106
	 */
107
	public $function	= NULL;
108
 
109
	/**
110
	 * Set the template from the table config file if it exists
111
	 *
112
	 * @param	array	$config	(default: array())
113
	 * @return	void
114
	 */
115
	public function __construct($config = array())
116
	{
117
		// initialize config
118
		foreach ($config as $key => $val)
119
		{
120
			$this->template[$key] = $val;
121
		}
122
 
123
		log_message('info', 'Table Class Initialized');
124
	}
125
 
126
	// --------------------------------------------------------------------
127
 
128
	/**
129
	 * Set the template
130
	 *
131
	 * @param	array	$template
132
	 * @return	bool
133
	 */
134
	public function set_template($template)
135
	{
136
		if ( ! is_array($template))
137
		{
138
			return FALSE;
139
		}
140
 
141
		$this->template = $template;
142
		return TRUE;
143
	}
144
 
145
	// --------------------------------------------------------------------
146
 
147
	/**
148
	 * Set the table heading
149
	 *
150
	 * Can be passed as an array or discreet params
151
	 *
152
	 * @param	mixed
153
	 * @return	CI_Table
154
	 */
155
	public function set_heading($args = array())
156
	{
157
		$this->heading = $this->_prep_args(func_get_args());
158
		return $this;
159
	}
160
 
161
	// --------------------------------------------------------------------
162
 
163
	/**
164
	 * Set columns. Takes a one-dimensional array as input and creates
165
	 * a multi-dimensional array with a depth equal to the number of
166
	 * columns. This allows a single array with many elements to be
167
	 * displayed in a table that has a fixed column count.
168
	 *
169
	 * @param	array	$array
170
	 * @param	int	$col_limit
171
	 * @return	array
172
	 */
173
	public function make_columns($array = array(), $col_limit = 0)
174
	{
175
		if ( ! is_array($array) OR count($array) === 0 OR ! is_int($col_limit))
176
		{
177
			return FALSE;
178
		}
179
 
180
		// Turn off the auto-heading feature since it's doubtful we
181
		// will want headings from a one-dimensional array
182
		$this->auto_heading = FALSE;
183
 
184
		if ($col_limit === 0)
185
		{
186
			return $array;
187
		}
188
 
189
		$new = array();
190
		do
191
		{
192
			$temp = array_splice($array, 0, $col_limit);
193
 
194
			if (count($temp) < $col_limit)
195
			{
196
				for ($i = count($temp); $i < $col_limit; $i++)
197
				{
198
					$temp[] = '&nbsp;';
199
				}
200
			}
201
 
202
			$new[] = $temp;
203
		}
204
		while (count($array) > 0);
205
 
206
		return $new;
207
	}
208
 
209
	// --------------------------------------------------------------------
210
 
211
	/**
212
	 * Set "empty" cells
213
	 *
214
	 * Can be passed as an array or discreet params
215
	 *
216
	 * @param	mixed	$value
217
	 * @return	CI_Table
218
	 */
219
	public function set_empty($value)
220
	{
221
		$this->empty_cells = $value;
222
		return $this;
223
	}
224
 
225
	// --------------------------------------------------------------------
226
 
227
	/**
228
	 * Add a table row
229
	 *
230
	 * Can be passed as an array or discreet params
231
	 *
232
	 * @param	mixed
233
	 * @return	CI_Table
234
	 */
235
	public function add_row($args = array())
236
	{
237
		$this->rows[] = $this->_prep_args(func_get_args());
238
		return $this;
239
	}
240
 
241
	// --------------------------------------------------------------------
242
 
243
	/**
244
	 * Prep Args
245
	 *
246
	 * Ensures a standard associative array format for all cell data
247
	 *
248
	 * @param	array
249
	 * @return	array
250
	 */
251
	protected function _prep_args($args)
252
	{
253
		// If there is no $args[0], skip this and treat as an associative array
254
		// This can happen if there is only a single key, for example this is passed to table->generate
255
		// array(array('foo'=>'bar'))
256
		if (isset($args[0]) && count($args) === 1 && is_array($args[0]) && ! isset($args[0]['data']))
257
		{
258
			$args = $args[0];
259
		}
260
 
261
		foreach ($args as $key => $val)
262
		{
263
			is_array($val) OR $args[$key] = array('data' => $val);
264
		}
265
 
266
		return $args;
267
	}
268
 
269
	// --------------------------------------------------------------------
270
 
271
	/**
272
	 * Add a table caption
273
	 *
274
	 * @param	string	$caption
275
	 * @return	CI_Table
276
	 */
277
	public function set_caption($caption)
278
	{
279
		$this->caption = $caption;
280
	}
281
 
282
	// --------------------------------------------------------------------
283
 
284
	/**
285
	 * Generate the table
286
	 *
287
	 * @param	mixed	$table_data
288
	 * @return	string
289
	 */
290
	public function generate($table_data = NULL)
291
	{
292
		// The table data can optionally be passed to this function
293
		// either as a database result object or an array
294
		if ( ! empty($table_data))
295
		{
296
			if ($table_data instanceof CI_DB_result)
297
			{
298
				$this->_set_from_db_result($table_data);
299
			}
300
			elseif (is_array($table_data))
301
			{
302
				$this->_set_from_array($table_data);
303
			}
304
		}
305
 
306
		// Is there anything to display? No? Smite them!
307
		if (empty($this->heading) && empty($this->rows))
308
		{
309
			return 'Undefined table data';
310
		}
311
 
312
		// Compile and validate the template date
313
		$this->_compile_template();
314
 
315
		// Validate a possibly existing custom cell manipulation function
316
		if (isset($this->function) && ! is_callable($this->function))
317
		{
318
			$this->function = NULL;
319
		}
320
 
321
		// Build the table!
322
 
323
		$out = $this->template['table_open'].$this->newline;
324
 
325
		// Add any caption here
326
		if ($this->caption)
327
		{
328
			$out .= '<caption>'.$this->caption.'</caption>'.$this->newline;
329
		}
330
 
331
		// Is there a table heading to display?
332
		if ( ! empty($this->heading))
333
		{
334
			$out .= $this->template['thead_open'].$this->newline.$this->template['heading_row_start'].$this->newline;
335
 
336
			foreach ($this->heading as $heading)
337
			{
338
				$temp = $this->template['heading_cell_start'];
339
 
340
				foreach ($heading as $key => $val)
341
				{
342
					if ($key !== 'data')
343
					{
344
						$temp = str_replace('<th', '<th '.$key.'="'.$val.'"', $temp);
345
					}
346
				}
347
 
348
				$out .= $temp.(isset($heading['data']) ? $heading['data'] : '').$this->template['heading_cell_end'];
349
			}
350
 
351
			$out .= $this->template['heading_row_end'].$this->newline.$this->template['thead_close'].$this->newline;
352
		}
353
 
354
		// Build the table rows
355
		if ( ! empty($this->rows))
356
		{
357
			$out .= $this->template['tbody_open'].$this->newline;
358
 
359
			$i = 1;
360
			foreach ($this->rows as $row)
361
			{
362
				if ( ! is_array($row))
363
				{
364
					break;
365
				}
366
 
367
				// We use modulus to alternate the row colors
368
				$name = fmod($i++, 2) ? '' : 'alt_';
369
 
370
				$out .= $this->template['row_'.$name.'start'].$this->newline;
371
 
372
				foreach ($row as $cell)
373
				{
374
					$temp = $this->template['cell_'.$name.'start'];
375
 
376
					foreach ($cell as $key => $val)
377
					{
378
						if ($key !== 'data')
379
						{
380
							$temp = str_replace('<td', '<td '.$key.'="'.$val.'"', $temp);
381
						}
382
					}
383
 
384
					$cell = isset($cell['data']) ? $cell['data'] : '';
385
					$out .= $temp;
386
 
387
					if ($cell === '' OR $cell === NULL)
388
					{
389
						$out .= $this->empty_cells;
390
					}
391
					elseif (isset($this->function))
392
					{
393
						$out .= call_user_func($this->function, $cell);
394
					}
395
					else
396
					{
397
						$out .= $cell;
398
					}
399
 
400
					$out .= $this->template['cell_'.$name.'end'];
401
				}
402
 
403
				$out .= $this->template['row_'.$name.'end'].$this->newline;
404
			}
405
 
406
			$out .= $this->template['tbody_close'].$this->newline;
407
		}
408
 
409
		$out .= $this->template['table_close'];
410
 
411
		// Clear table class properties before generating the table
412
		$this->clear();
413
 
414
		return $out;
415
	}
416
 
417
	// --------------------------------------------------------------------
418
 
419
	/**
420
	 * Clears the table arrays.  Useful if multiple tables are being generated
421
	 *
422
	 * @return	CI_Table
423
	 */
424
	public function clear()
425
	{
426
		$this->rows = array();
427
		$this->heading = array();
428
		$this->auto_heading = TRUE;
429
		return $this;
430
	}
431
 
432
	// --------------------------------------------------------------------
433
 
434
	/**
435
	 * Set table data from a database result object
436
	 *
437
	 * @param	CI_DB_result	$db_result	Database result object
438
	 * @return	void
439
	 */
440
	protected function _set_from_db_result($object)
441
	{
442
		// First generate the headings from the table column names
443
		if ($this->auto_heading === TRUE && empty($this->heading))
444
		{
445
			$this->heading = $this->_prep_args($object->list_fields());
446
		}
447
 
448
		foreach ($object->result_array() as $row)
449
		{
450
			$this->rows[] = $this->_prep_args($row);
451
		}
452
	}
453
 
454
	// --------------------------------------------------------------------
455
 
456
	/**
457
	 * Set table data from an array
458
	 *
459
	 * @param	array	$data
460
	 * @return	void
461
	 */
462
	protected function _set_from_array($data)
463
	{
464
		if ($this->auto_heading === TRUE && empty($this->heading))
465
		{
466
			$this->heading = $this->_prep_args(array_shift($data));
467
		}
468
 
469
		foreach ($data as &$row)
470
		{
471
			$this->rows[] = $this->_prep_args($row);
472
		}
473
	}
474
 
475
	// --------------------------------------------------------------------
476
 
477
	/**
478
	 * Compile Template
479
	 *
480
	 * @return	void
481
	 */
482
	protected function _compile_template()
483
	{
484
		if ($this->template === NULL)
485
		{
486
			$this->template = $this->_default_template();
487
			return;
488
		}
489
 
490
		$this->temp = $this->_default_template();
491
		foreach (array('table_open', 'thead_open', 'thead_close', 'heading_row_start', 'heading_row_end', 'heading_cell_start', 'heading_cell_end', 'tbody_open', 'tbody_close', 'row_start', 'row_end', 'cell_start', 'cell_end', 'row_alt_start', 'row_alt_end', 'cell_alt_start', 'cell_alt_end', 'table_close') as $val)
492
		{
493
			if ( ! isset($this->template[$val]))
494
			{
495
				$this->template[$val] = $this->temp[$val];
496
			}
497
		}
498
	}
499
 
500
	// --------------------------------------------------------------------
501
 
502
	/**
503
	 * Default Template
504
	 *
505
	 * @return	array
506
	 */
507
	protected function _default_template()
508
	{
509
		return array(
510
			'table_open'		=> '<table border="0" cellpadding="4" cellspacing="0">',
511
 
512
			'thead_open'		=> '<thead>',
513
			'thead_close'		=> '</thead>',
514
 
515
			'heading_row_start'	=> '<tr>',
516
			'heading_row_end'	=> '</tr>',
517
			'heading_cell_start'	=> '<th>',
518
			'heading_cell_end'	=> '</th>',
519
 
520
			'tbody_open'		=> '<tbody>',
521
			'tbody_close'		=> '</tbody>',
522
 
523
			'row_start'		=> '<tr>',
524
			'row_end'		=> '</tr>',
525
			'cell_start'		=> '<td>',
526
			'cell_end'		=> '</td>',
527
 
528
			'row_alt_start'		=> '<tr>',
529
			'row_alt_end'		=> '</tr>',
530
			'cell_alt_start'	=> '<td>',
531
			'cell_alt_end'		=> '</td>',
532
 
533
			'table_close'		=> '</table>'
534
		);
535
	}
536
 
537
}