blob: 8d0e11a43fd0ee43d0cdf92871f90c7f703f97a6 [file] [log] [blame]
Derek Jones4b9c6292011-07-01 17:40:48 -05001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Greg Aker741de1c2010-11-10 14:52:57 -06005 * An open source application development framework for PHP 5.1.6 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
8 *
9 * Licensed under the Open Software License version 3.0
10 *
11 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
21 * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
22 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.3.1
25 * @filesource
26 */
27
28// ------------------------------------------------------------------------
29
30/**
31 * HTML Table Generating Class
32 *
33 * Lets you create tables manually or from database result objects, or arrays.
34 *
35 * @package CodeIgniter
36 * @subpackage Libraries
37 * @category HTML Tables
Derek Jonesf4a4bd82011-10-20 12:18:42 -050038 * @author EllisLab Dev Team
Gerry6b590892011-09-25 00:16:39 +080039 * @link http://codeigniter.com/user_guide/libraries/table.html
Derek Allard2067d1a2008-11-13 22:59:24 +000040 */
41class CI_Table {
42
43 var $rows = array();
44 var $heading = array();
Barry Mienydd671972010-10-04 16:33:58 +020045 var $auto_heading = TRUE;
46 var $caption = NULL;
47 var $template = NULL;
Derek Allard2067d1a2008-11-13 22:59:24 +000048 var $newline = "\n";
49 var $empty_cells = "";
Derek Jones7b5b0e22010-03-02 22:48:53 -060050 var $function = FALSE;
Barry Mienydd671972010-10-04 16:33:58 +020051
Greg Akera9263282010-11-10 15:26:43 -060052 public function __construct()
Derek Allard2067d1a2008-11-13 22:59:24 +000053 {
54 log_message('debug', "Table Class Initialized");
55 }
56
57 // --------------------------------------------------------------------
58
59 /**
60 * Set the template
61 *
62 * @access public
63 * @param array
64 * @return void
65 */
66 function set_template($template)
67 {
68 if ( ! is_array($template))
69 {
70 return FALSE;
71 }
Barry Mienydd671972010-10-04 16:33:58 +020072
Derek Allard2067d1a2008-11-13 22:59:24 +000073 $this->template = $template;
74 }
75
76 // --------------------------------------------------------------------
77
78 /**
79 * Set the table heading
80 *
81 * Can be passed as an array or discreet params
82 *
83 * @access public
84 * @param mixed
85 * @return void
86 */
87 function set_heading()
88 {
89 $args = func_get_args();
Derek Jones7b5b0e22010-03-02 22:48:53 -060090 $this->heading = $this->_prep_args($args);
Derek Allard2067d1a2008-11-13 22:59:24 +000091 }
92
93 // --------------------------------------------------------------------
94
95 /**
Derek Jones4b9c6292011-07-01 17:40:48 -050096 * Set columns. Takes a one-dimensional array as input and creates
Derek Allard2067d1a2008-11-13 22:59:24 +000097 * a multi-dimensional array with a depth equal to the number of
Derek Jones4b9c6292011-07-01 17:40:48 -050098 * columns. This allows a single array with many elements to be
Derek Allard2067d1a2008-11-13 22:59:24 +000099 * displayed in a table that has a fixed column count.
100 *
101 * @access public
102 * @param array
103 * @param int
104 * @return void
105 */
106 function make_columns($array = array(), $col_limit = 0)
107 {
108 if ( ! is_array($array) OR count($array) == 0)
109 {
110 return FALSE;
111 }
Barry Mienydd671972010-10-04 16:33:58 +0200112
113 // Turn off the auto-heading feature since it's doubtful we
Derek Allard2067d1a2008-11-13 22:59:24 +0000114 // will want headings from a one-dimensional array
115 $this->auto_heading = FALSE;
Barry Mienydd671972010-10-04 16:33:58 +0200116
Derek Allard2067d1a2008-11-13 22:59:24 +0000117 if ($col_limit == 0)
118 {
119 return $array;
120 }
Barry Mienydd671972010-10-04 16:33:58 +0200121
Derek Allard2067d1a2008-11-13 22:59:24 +0000122 $new = array();
Pascal Kriete14287f32011-02-14 13:39:34 -0500123 while (count($array) > 0)
Barry Mienydd671972010-10-04 16:33:58 +0200124 {
125 $temp = array_splice($array, 0, $col_limit);
126
Derek Allard2067d1a2008-11-13 22:59:24 +0000127 if (count($temp) < $col_limit)
128 {
129 for ($i = count($temp); $i < $col_limit; $i++)
130 {
131 $temp[] = '&nbsp;';
132 }
133 }
Barry Mienydd671972010-10-04 16:33:58 +0200134
Derek Allard2067d1a2008-11-13 22:59:24 +0000135 $new[] = $temp;
136 }
Barry Mienydd671972010-10-04 16:33:58 +0200137
Derek Allard2067d1a2008-11-13 22:59:24 +0000138 return $new;
139 }
140
141 // --------------------------------------------------------------------
142
143 /**
144 * Set "empty" cells
145 *
146 * Can be passed as an array or discreet params
147 *
148 * @access public
149 * @param mixed
150 * @return void
151 */
152 function set_empty($value)
153 {
154 $this->empty_cells = $value;
155 }
Barry Mienydd671972010-10-04 16:33:58 +0200156
Derek Allard2067d1a2008-11-13 22:59:24 +0000157 // --------------------------------------------------------------------
158
159 /**
160 * Add a table row
161 *
162 * Can be passed as an array or discreet params
163 *
164 * @access public
165 * @param mixed
166 * @return void
167 */
168 function add_row()
169 {
170 $args = func_get_args();
Derek Jones7b5b0e22010-03-02 22:48:53 -0600171 $this->rows[] = $this->_prep_args($args);
Derek Allard2067d1a2008-11-13 22:59:24 +0000172 }
173
174 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200175
Derek Jones7b5b0e22010-03-02 22:48:53 -0600176 /**
177 * Prep Args
178 *
179 * Ensures a standard associative array format for all cell data
180 *
181 * @access public
182 * @param type
183 * @return type
184 */
185 function _prep_args($args)
186 {
187 // If there is no $args[0], skip this and treat as an associative array
188 // This can happen if there is only a single key, for example this is passed to table->generate
189 // array(array('foo'=>'bar'))
190 if (isset($args[0]) AND (count($args) == 1 && is_array($args[0])))
191 {
192 // args sent as indexed array
193 if ( ! isset($args[0]['data']))
194 {
195 foreach ($args[0] as $key => $val)
196 {
197 if (is_array($val) && isset($val['data']))
198 {
199 $args[$key] = $val;
200 }
201 else
202 {
Barry Mienydd671972010-10-04 16:33:58 +0200203 $args[$key] = array('data' => $val);
Derek Jones7b5b0e22010-03-02 22:48:53 -0600204 }
Barry Mienydd671972010-10-04 16:33:58 +0200205 }
Derek Jones7b5b0e22010-03-02 22:48:53 -0600206 }
207 }
208 else
209 {
210 foreach ($args as $key => $val)
211 {
212 if ( ! is_array($val))
213 {
214 $args[$key] = array('data' => $val);
215 }
216 }
217 }
Barry Mienydd671972010-10-04 16:33:58 +0200218
Derek Jones7b5b0e22010-03-02 22:48:53 -0600219 return $args;
220 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000221
Derek Jones7b5b0e22010-03-02 22:48:53 -0600222 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200223
Derek Allard2067d1a2008-11-13 22:59:24 +0000224 /**
225 * Add a table caption
226 *
227 * @access public
228 * @param string
229 * @return void
230 */
231 function set_caption($caption)
232 {
233 $this->caption = $caption;
Barry Mienydd671972010-10-04 16:33:58 +0200234 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000235
236 // --------------------------------------------------------------------
237
238 /**
239 * Generate the table
240 *
241 * @access public
242 * @param mixed
243 * @return string
244 */
245 function generate($table_data = NULL)
246 {
247 // The table data can optionally be passed to this function
248 // either as a database result object or an array
249 if ( ! is_null($table_data))
250 {
251 if (is_object($table_data))
252 {
253 $this->_set_from_object($table_data);
254 }
255 elseif (is_array($table_data))
256 {
257 $set_heading = (count($this->heading) == 0 AND $this->auto_heading == FALSE) ? FALSE : TRUE;
258 $this->_set_from_array($table_data, $set_heading);
259 }
260 }
Barry Mienydd671972010-10-04 16:33:58 +0200261
Derek Jones4b9c6292011-07-01 17:40:48 -0500262 // Is there anything to display? No? Smite them!
Derek Allard2067d1a2008-11-13 22:59:24 +0000263 if (count($this->heading) == 0 AND count($this->rows) == 0)
264 {
265 return 'Undefined table data';
266 }
Barry Mienydd671972010-10-04 16:33:58 +0200267
Derek Allard2067d1a2008-11-13 22:59:24 +0000268 // Compile and validate the template date
269 $this->_compile_template();
Barry Mienydd671972010-10-04 16:33:58 +0200270
Derek Jones7b5b0e22010-03-02 22:48:53 -0600271 // set a custom cell manipulation function to a locally scoped variable so its callable
272 $function = $this->function;
Barry Mienydd671972010-10-04 16:33:58 +0200273
Derek Allard2067d1a2008-11-13 22:59:24 +0000274 // Build the table!
Barry Mienydd671972010-10-04 16:33:58 +0200275
Derek Allard2067d1a2008-11-13 22:59:24 +0000276 $out = $this->template['table_open'];
Barry Mienydd671972010-10-04 16:33:58 +0200277 $out .= $this->newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000278
279 // Add any caption here
280 if ($this->caption)
281 {
282 $out .= $this->newline;
283 $out .= '<caption>' . $this->caption . '</caption>';
284 $out .= $this->newline;
285 }
286
287 // Is there a table heading to display?
288 if (count($this->heading) > 0)
289 {
Derek Jones7b5b0e22010-03-02 22:48:53 -0600290 $out .= $this->template['thead_open'];
291 $out .= $this->newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000292 $out .= $this->template['heading_row_start'];
Derek Jones7b5b0e22010-03-02 22:48:53 -0600293 $out .= $this->newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000294
Pascal Kriete14287f32011-02-14 13:39:34 -0500295 foreach ($this->heading as $heading)
Derek Allard2067d1a2008-11-13 22:59:24 +0000296 {
Derek Jones7b5b0e22010-03-02 22:48:53 -0600297 $temp = $this->template['heading_cell_start'];
Barry Mienydd671972010-10-04 16:33:58 +0200298
Derek Jones7b5b0e22010-03-02 22:48:53 -0600299 foreach ($heading as $key => $val)
300 {
301 if ($key != 'data')
302 {
303 $temp = str_replace('<th', "<th $key='$val'", $temp);
Barry Mienydd671972010-10-04 16:33:58 +0200304 }
Derek Jones7b5b0e22010-03-02 22:48:53 -0600305 }
306
Barry Mienydd671972010-10-04 16:33:58 +0200307 $out .= $temp;
Derek Jones7b5b0e22010-03-02 22:48:53 -0600308 $out .= isset($heading['data']) ? $heading['data'] : '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000309 $out .= $this->template['heading_cell_end'];
310 }
311
312 $out .= $this->template['heading_row_end'];
Derek Jones7b5b0e22010-03-02 22:48:53 -0600313 $out .= $this->newline;
314 $out .= $this->template['thead_close'];
315 $out .= $this->newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000316 }
Barry Mienydd671972010-10-04 16:33:58 +0200317
Derek Allard2067d1a2008-11-13 22:59:24 +0000318 // Build the table rows
319 if (count($this->rows) > 0)
320 {
Derek Jones7b5b0e22010-03-02 22:48:53 -0600321 $out .= $this->template['tbody_open'];
322 $out .= $this->newline;
Barry Mienydd671972010-10-04 16:33:58 +0200323
Derek Allard2067d1a2008-11-13 22:59:24 +0000324 $i = 1;
Pascal Kriete14287f32011-02-14 13:39:34 -0500325 foreach ($this->rows as $row)
Derek Allard2067d1a2008-11-13 22:59:24 +0000326 {
327 if ( ! is_array($row))
328 {
329 break;
330 }
Barry Mienydd671972010-10-04 16:33:58 +0200331
Derek Allard2067d1a2008-11-13 22:59:24 +0000332 // We use modulus to alternate the row colors
333 $name = (fmod($i++, 2)) ? '' : 'alt_';
Barry Mienydd671972010-10-04 16:33:58 +0200334
Derek Allard2067d1a2008-11-13 22:59:24 +0000335 $out .= $this->template['row_'.$name.'start'];
Barry Mienydd671972010-10-04 16:33:58 +0200336 $out .= $this->newline;
337
Pascal Kriete14287f32011-02-14 13:39:34 -0500338 foreach ($row as $cell)
Derek Allard2067d1a2008-11-13 22:59:24 +0000339 {
Derek Jones7b5b0e22010-03-02 22:48:53 -0600340 $temp = $this->template['cell_'.$name.'start'];
Barry Mienydd671972010-10-04 16:33:58 +0200341
Derek Jones7b5b0e22010-03-02 22:48:53 -0600342 foreach ($cell as $key => $val)
343 {
344 if ($key != 'data')
345 {
346 $temp = str_replace('<td', "<td $key='$val'", $temp);
Barry Mienydd671972010-10-04 16:33:58 +0200347 }
Derek Jones7b5b0e22010-03-02 22:48:53 -0600348 }
Barry Mienydd671972010-10-04 16:33:58 +0200349
Derek Jones7b5b0e22010-03-02 22:48:53 -0600350 $cell = isset($cell['data']) ? $cell['data'] : '';
351 $out .= $temp;
352
Derek Allardd8270582010-01-15 17:10:56 +0000353 if ($cell === "" OR $cell === NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000354 {
355 $out .= $this->empty_cells;
356 }
357 else
358 {
Derek Jones7b5b0e22010-03-02 22:48:53 -0600359 if ($function !== FALSE && is_callable($function))
360 {
Phil Sturgeon6c597f82010-12-27 17:35:35 +0000361 $out .= call_user_func($function, $cell);
Derek Jones7b5b0e22010-03-02 22:48:53 -0600362 }
363 else
364 {
365 $out .= $cell;
366 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000367 }
Barry Mienydd671972010-10-04 16:33:58 +0200368
Derek Allard2067d1a2008-11-13 22:59:24 +0000369 $out .= $this->template['cell_'.$name.'end'];
370 }
Barry Mienydd671972010-10-04 16:33:58 +0200371
Derek Allard2067d1a2008-11-13 22:59:24 +0000372 $out .= $this->template['row_'.$name.'end'];
Barry Mienydd671972010-10-04 16:33:58 +0200373 $out .= $this->newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000374 }
Barry Mienydd671972010-10-04 16:33:58 +0200375
Derek Jones7b5b0e22010-03-02 22:48:53 -0600376 $out .= $this->template['tbody_close'];
377 $out .= $this->newline;
Derek Allard2067d1a2008-11-13 22:59:24 +0000378 }
379
380 $out .= $this->template['table_close'];
Barry Mienydd671972010-10-04 16:33:58 +0200381
Greg Aker02b3a5b2011-02-01 01:29:21 -0600382 // Clear table class properties before generating the table
383 $this->clear();
384
Derek Allard2067d1a2008-11-13 22:59:24 +0000385 return $out;
386 }
Barry Mienydd671972010-10-04 16:33:58 +0200387
Derek Allard2067d1a2008-11-13 22:59:24 +0000388 // --------------------------------------------------------------------
389
390 /**
Derek Jones4b9c6292011-07-01 17:40:48 -0500391 * Clears the table arrays. Useful if multiple tables are being generated
Derek Allard2067d1a2008-11-13 22:59:24 +0000392 *
393 * @access public
394 * @return void
395 */
396 function clear()
397 {
398 $this->rows = array();
399 $this->heading = array();
Barry Mienydd671972010-10-04 16:33:58 +0200400 $this->auto_heading = TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000401 }
Barry Mienydd671972010-10-04 16:33:58 +0200402
Derek Allard2067d1a2008-11-13 22:59:24 +0000403 // --------------------------------------------------------------------
404
405 /**
406 * Set table data from a database result object
407 *
408 * @access public
409 * @param object
410 * @return void
411 */
412 function _set_from_object($query)
413 {
414 if ( ! is_object($query))
415 {
416 return FALSE;
417 }
Barry Mienydd671972010-10-04 16:33:58 +0200418
Derek Allard2067d1a2008-11-13 22:59:24 +0000419 // First generate the headings from the table column names
420 if (count($this->heading) == 0)
421 {
422 if ( ! method_exists($query, 'list_fields'))
423 {
424 return FALSE;
425 }
Barry Mienydd671972010-10-04 16:33:58 +0200426
Derek Jones7b5b0e22010-03-02 22:48:53 -0600427 $this->heading = $this->_prep_args($query->list_fields());
Derek Allard2067d1a2008-11-13 22:59:24 +0000428 }
Barry Mienydd671972010-10-04 16:33:58 +0200429
Derek Allard2067d1a2008-11-13 22:59:24 +0000430 // Next blast through the result array and build out the rows
Barry Mienydd671972010-10-04 16:33:58 +0200431
Derek Allard2067d1a2008-11-13 22:59:24 +0000432 if ($query->num_rows() > 0)
433 {
434 foreach ($query->result_array() as $row)
435 {
Derek Jones7b5b0e22010-03-02 22:48:53 -0600436 $this->rows[] = $this->_prep_args($row);
Derek Allard2067d1a2008-11-13 22:59:24 +0000437 }
438 }
439 }
440
441 // --------------------------------------------------------------------
442
443 /**
444 * Set table data from an array
445 *
446 * @access public
447 * @param array
448 * @return void
449 */
450 function _set_from_array($data, $set_heading = TRUE)
451 {
452 if ( ! is_array($data) OR count($data) == 0)
453 {
454 return FALSE;
455 }
Barry Mienydd671972010-10-04 16:33:58 +0200456
Derek Allard2067d1a2008-11-13 22:59:24 +0000457 $i = 0;
458 foreach ($data as $row)
Barry Mienydd671972010-10-04 16:33:58 +0200459 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000460 // If a heading hasn't already been set we'll use the first row of the array as the heading
461 if ($i == 0 AND count($data) > 1 AND count($this->heading) == 0 AND $set_heading == TRUE)
462 {
Derek Jones7b5b0e22010-03-02 22:48:53 -0600463 $this->heading = $this->_prep_args($row);
Derek Allard2067d1a2008-11-13 22:59:24 +0000464 }
465 else
466 {
Derek Jones7b5b0e22010-03-02 22:48:53 -0600467 $this->rows[] = $this->_prep_args($row);
Derek Allard2067d1a2008-11-13 22:59:24 +0000468 }
Barry Mienydd671972010-10-04 16:33:58 +0200469
Derek Allard2067d1a2008-11-13 22:59:24 +0000470 $i++;
471 }
472 }
473
474 // --------------------------------------------------------------------
475
476 /**
477 * Compile Template
478 *
479 * @access private
480 * @return void
481 */
Barry Mienydd671972010-10-04 16:33:58 +0200482 function _compile_template()
483 {
484 if ($this->template == NULL)
485 {
486 $this->template = $this->_default_template();
487 return;
488 }
489
Derek Allard2067d1a2008-11-13 22:59:24 +0000490 $this->temp = $this->_default_template();
Derek Jones7b5b0e22010-03-02 22:48:53 -0600491 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)
Derek Allard2067d1a2008-11-13 22:59:24 +0000492 {
493 if ( ! isset($this->template[$val]))
494 {
495 $this->template[$val] = $this->temp[$val];
496 }
Barry Mienydd671972010-10-04 16:33:58 +0200497 }
498 }
499
Derek Allard2067d1a2008-11-13 22:59:24 +0000500 // --------------------------------------------------------------------
501
502 /**
503 * Default Template
504 *
505 * @access private
506 * @return void
507 */
508 function _default_template()
509 {
Derek Jones4b9c6292011-07-01 17:40:48 -0500510 return array (
Barry Mienydd671972010-10-04 16:33:58 +0200511 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">',
512
Derek Jones7b5b0e22010-03-02 22:48:53 -0600513 'thead_open' => '<thead>',
514 'thead_close' => '</thead>',
Barry Mienydd671972010-10-04 16:33:58 +0200515
516 'heading_row_start' => '<tr>',
517 'heading_row_end' => '</tr>',
Derek Allard2067d1a2008-11-13 22:59:24 +0000518 'heading_cell_start' => '<th>',
519 'heading_cell_end' => '</th>',
520
Derek Jones7b5b0e22010-03-02 22:48:53 -0600521 'tbody_open' => '<tbody>',
522 'tbody_close' => '</tbody>',
Barry Mienydd671972010-10-04 16:33:58 +0200523
524 'row_start' => '<tr>',
525 'row_end' => '</tr>',
Derek Allard2067d1a2008-11-13 22:59:24 +0000526 'cell_start' => '<td>',
527 'cell_end' => '</td>',
528
Barry Mienydd671972010-10-04 16:33:58 +0200529 'row_alt_start' => '<tr>',
530 'row_alt_end' => '</tr>',
Derek Allard2067d1a2008-11-13 22:59:24 +0000531 'cell_alt_start' => '<td>',
532 'cell_alt_end' => '</td>',
533
Barry Mienydd671972010-10-04 16:33:58 +0200534 'table_close' => '</table>'
535 );
Derek Allard2067d1a2008-11-13 22:59:24 +0000536 }
Barry Mienydd671972010-10-04 16:33:58 +0200537
Derek Allard2067d1a2008-11-13 22:59:24 +0000538
539}
540
541
542/* End of file Table.php */
Gerry6b590892011-09-25 00:16:39 +0800543/* Location: ./system/libraries/Table.php */