[Fixes to misc; xassert() -> assert(), break row support in ListPlank, pagination improvements tom@wwworldmedia.com**20050915175425] { hunk ./GangplankDbMysql.php 131 - // hunk ./GangplankDbMysql.php 132 - // hunk ./GangplankEdit.php 44 + $this->virtual_column_types[] = "MappedKey"; hunk ./GangplankEdit.php 151 - xassert(is_array($data), "Could not load data row "); + assert(is_array($data)); hunk ./GangplankEdit.php 688 - xassert(!empty($this->cols[$local_col]), "No such local column: $local_col"); + assert(!empty($this->cols[$local_col])); hunk ./GangplankEdit.php 726 + } + + // --[ The "MappedKey" Virtual Column Type ]-- + + // Validate virtual data used for ListGangplank MappedKey columns. The data must + // be non-blank, an array, and may have these indices: + // + // * $data["local_key"] -> the joining key in our local table (optional; default = pri key) + // * $data["map_table"] -> the table that holds the mapping + // * $data["map_local_key"] -> the local key column's name in the map table (optional) + // * $data["map_foreign_key"] -> the foreign key column's name in the map table (optional) + // * $data["map_where"] -> a WHERE clause used when doing the mapping (optional) + // * $data["foreign_table"] -> the foreign table + // * $data["foreign_key"] -> the primary key in the remote table + // * $data["foreign_desc"] -> the column that we'll display as an identifier of the row. + // * $data["foreign_where"] -> a WHERE clause used on the foreign table + // (this is usually a title or description field) + // + function validateVirtualMappedKeyData($data, &$error_text) { + if (! is_array($data)) { + $error_text = "Data must be an array"; + return false; + } + /* validate required fields */ + if (empty($data["map_table"])) { + $error_text = "\"map_table\" (name of table containing mapped relationship) not found."; + return false; + } + if (empty($data["foreign_table"])) { + $error_text = "Missing \"foreign_table\" element"; + return false; + } + if (empty($data["foreign_key"])) { + $error_text = "Missing \"foreign_key\" element"; + return false; + } + if (empty($data["foreign_desc"])) { + $error_text = "Missing \"foreign_desc\" element"; + return false; + } + /* optional fields */ + if (empty($data["local_key"])) { + if (empty($this->primary_key)) { + $error_text = "\"local_key\" not specified and not primary key found."; + return false; + } + $data["local_key"] = $this->primary_key; + } + if (empty($data["map_local_key"])) { + $data["map_local_key"] = $data["local_key"]; + } + if (empty($data["map_foreign_key"])) { + $map["map_foreign_key"] = $data["foreign_key"]; + } + return true; + } + + // Render a virtual column that refers to another table. + function renderVirtualMappedKey($row, $col) { + $name = $col["name"]; + $data = $col["virtual_data"]; + + if (!empty($col["help_text"])) + $help = "$col[help_text]"; + else + $help = ""; + + $label = $col["label"]; + if (! empty($data["link_contents_to"])) { + $link = $data["link_contents_to"]; + $label = "$col[label]"; + } + + $local_key = $data["local_key"]; + $local_key_val = gp_escapeSql($row[$local_key]); + $map_table = $data["map_table"]; + $map_local_key = $data["map_local_key"]; + $map_foreign_key = $data["map_foreign_key"]; + if (!empty($data["map_where"])) + $map_where = "and " . $data["map_where"]; + else + $map_where = ""; + $foreign_table = $data["foreign_table"]; + $foreign_key = $data["foreign_key"]; + $foreign_desc = $data["foreign_desc"]; + if (!empty($data["foreign_where"])) + $foreign_where = "and " . $data["foreign_where"]; + else + $foreign_where = ""; + + $qs = " + select $map_foreign_key + from $map_table + where $map_local_key = '$local_key_val' + $map_where "; + $map = gp_all_rows_as_array($qs, $map_foreign_key); + print_r($map); + + $qs = " + select $foreign_key, $foreign_desc + from $foreign_table + where $foreign_desc <> '' + $foreign_where + order by $foreign_desc + "; + $foreign_rows = gp_all_rows($qs); + + $html = " + + $help"; + foreach ($foreign_rows as $option) { + $field_name = $name . "[]"; + $desc = hsc($option[$foreign_desc]); + $f_key = $option[$foreign_key]; + $check = isset($map[$f_key]) ? "checked" : ""; + $html .= " $desc
\n"; + } + return $html; + } + + function saveVirtualMappedKey($row, $col) { + $data = $col["virtual_data"]; + $name = $col["name"]; + $vals = $_POST[$name]; + + $local_key = $data["local_key"]; + $local_key_val = gp_escapeSql($row[$local_key]); + $map_table = $data["map_table"]; + $map_local_key = $data["map_local_key"]; + $map_foreign_key = $data["map_foreign_key"]; + if (!empty($data["map_where"])) + $map_where = "and " . $data["map_where"]; + else + $map_where = ""; + $foreign_table = $data["foreign_table"]; + $foreign_key = $data["foreign_key"]; + $foreign_desc = $data["foreign_desc"]; + if (!empty($data["foreign_where"])) + $foreign_where = "and " . $data["foreign_where"]; + else + $foreign_where = ""; + + gp_update(" + delete from $map_table + where $map_local_key = '$local_key_val' + $map_where "); + + foreach ($vals as $key_to_ins) { + gp_update(" + insert into $map_table + ($map_local_key, $map_foreign_key) + values + ('$local_key_val', '$key_to_ins') "); + } + + // don't do anything extra to the main query. + return ""; hunk ./GangplankList.php 42 + /* stuff to support break rows */ + $this->use_break_rows = 0; + $this->break_row_columns = array(); + $this->break_row_values = array(); + $this->break_row_callbacks = array(); + hunk ./GangplankList.php 81 + // Set a callback to be called whenever the value of $column changes from what + // it was in the previous rows. You better add an order by on this column or + // chaos will ensue. + function setBreakRow($column, $callback) { + $this->loadColumns(); + if (empty($column) || empty($this->cols[$column])) + gp_die("setBreakRow(): Break row column \"$column\" is unknown."); + if (!is_callable($callback)) + gp_die("setBreakRow(): Callback is not callable"); + $this->use_break_rows++; + $this->break_row_columns[$column] = $column; + $this->break_row_values[$column] = (rand() % 99999) . (rand() % 99999); + $this->break_row_callbacks[$column] = $callback; + } + + function clearBreakRow($column) { + if (in_array($column, $this->break_row_columns)) { + $this->use_break_rows--; + unset($this->break_row_columns[$column]); + unset($this->break_row_values[$column]); + unset($this->break_row_callbacks[$column]); + } + } + hunk ./GangplankList.php 246 - function renderPageLink($page_num, $cur_page_n, $this_idx) { + function renderPageLink($page_num, $cur_page_num, $this_idx, $link_text = false) { + if (! $link_text) + $link_text = $page_num; + hunk ./GangplankList.php 251 - if ($page_num == $cur_page_n) - $html = " $page_num "; + + if ($page_num == $cur_page_num) + $html = " $link_text "; hunk ./GangplankList.php 259 - $html = "$page_num "; + $html = "$link_text "; hunk ./GangplankList.php 312 - $html = $this->renderPageLink(1, $cur_page_n, 0) . " ... " . $html; + $html = $this->renderPageLink(1, $cur_page_n, 0) . " … " . $html; hunk ./GangplankList.php 318 - $html = $html . " ... " . $this->renderPageLink(1, $cur_page_n, 0); + $html = $html . " … " . $this->renderPageLink($last_page_num, $cur_page_n, $this_idx); hunk ./GangplankList.php 326 + $prev = "« Prev"; + if ($cur_page_n > 1) { + $this_idx = ($cur_page_n - 2) * $per; + $label = $this->renderPageLink($cur_page_n - 1, $cur_page_n, $this_idx, $prev) . " " . $label; + } else { + $label = "$prev $label"; + } + + $next = "Next »"; + if ($cur_page_n < $last_page_num) { + $this_idx = ($cur_page_n + 1 - 1) * $per; + $label = $label . " " . $this->renderPageLink($last_page_num, $cur_page_n, $this_idx, $next); + } else { + $label = "$label $next"; + } + hunk ./GangplankList.php 524 + + if ($this->use_break_rows) { + foreach ($this->break_row_columns as $br_col) { + if ($row[$br_col] != $this->break_row_values[$br_col]) { + $html .= call_user_func($this->break_row_callbacks[$br_col], $row, $this->cols[$br_col]); + $this->break_row_values[$br_col] = $row[$br_col]; + } + } + } + hunk ./GangplankList.php 538 - hunk ./GangplankMisc.php 71 - if (isset($this->max_col_length)) - $max_col_len = $this->max_col_length; - else + if (!$max_col_len) }