00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 require_once dirname(__FILE__).'/diogenes.misc.inc.php';
00023 require_once dirname(__FILE__).'/diogenes.database.table.inc.php';
00024
00031 class DiogenesTableEditor extends DiogenesDatabaseTable {
00033 var $actions;
00035 var $autoinc;
00037 var $id;
00039 var $idedit;
00041 var $idsum = true;
00043 var $idfield;
00045 var $jtables = array();
00047 var $wheres = array();
00050 var $prefix = "frm_";
00052 var $readonly = false;
00054 var $maxrows = 0;
00055
00057 var $table_class = "light";
00059 var $table_style = "";
00060
00067 function DiogenesTableEditor($table, $idfield, $idedit = false) {
00068 global $globals;
00069 if (!is_object($globals->db))
00070 die("\$globals->db is not an object!");
00071
00072 $this->DiogenesDatabaseTable($globals->db,$table);
00073
00074 $this->actions = array();
00075
00076 if (!isset($this->vars[$idfield]))
00077 die("the field '$idfield' was not found in '$table'");
00078 $this->idfield = $idfield;
00079 $extra = new flagset($this->vars[$idfield]["extra"]);
00080 $this->autoinc = $extra->hasflag("auto_increment");
00081 $this->idedit = $idedit;
00082
00083
00084 if (!$this->idedit)
00085 unset($this->vars[$idfield]);
00086 }
00087
00088
00095 function addAction($text,$url)
00096 {
00097 array_push($this->actions, array("text" => $text, "url" =>$url));
00098 }
00099
00100
00111 function add_join_table($name,$joinid,$joindel,$joinextra="") {
00112 $this->jtables[$name] = array("joinid" => $joinid,"joindel" => $joindel,
00113 "joinextra" => $joinextra);
00114 }
00115
00116
00127 function add_join_field($table,$name,$field,$value,$desc,$sum,$type="text") {
00128 $this->vars[$name] = array("table" => $table, "field" => $field, "type" => $type,
00129 "value" => $value, "desc" => $desc, "sum" => $sum);
00130 }
00131
00132
00137 function add_where_condition($cond) {
00138 array_push($this->wheres, $cond);
00139 }
00140
00141
00146 function delete_db($id) {
00147 if ($id != '') {
00148 $this->dbh->query("delete from {$this->table} where {$this->idfield}='$id'");
00149
00150
00151 foreach ($this->jtables as $key => $val) {
00152 if ($val['joindel']) {
00153 $sql = "delete from {$key} where {$val['joinid']}='$id'";
00154 if ($val['joinextra'])
00155 $sql .= " and {$val['joinextra']}";
00156 $this->dbh->query($sql);
00157 }
00158 }
00159 reset($this->jtables);
00160 }
00161 }
00162
00163
00173 function describe($name,$desc,$sum,$type='',$value='',$trans=null) {
00174 if (!isset($this->vars[$name]))
00175 die("unknown field $name");
00176 $this->vars[$name]["desc"] = $desc;
00177 $this->vars[$name]["sum"] = $sum;
00178 if (!empty($type))
00179 $this->vars[$name]["type"] = $type;
00180 if (!empty($value))
00181 $this->vars[$name]["value"] = $value;
00182 if (!empty($trans) and $type=="set")
00183 $this->vars[$name]["trans"] = $trans;
00184 }
00185
00186
00196 function describe_join_value($name,$desc,$sum,$vtable,$vjoinid,$vfield) {
00197 global $globals;
00198 if (!isset($this->vars[$name]))
00199 die("unknown field $name");
00200 $this->vars[$name]["desc"] = $desc;
00201 $this->vars[$name]["sum"] = $sum;
00202 $this->vars[$name]["type"] = "ext";
00203
00204 $this->vars[$name]["vtable"] = $vtable;
00205 $this->vars[$name]["vjoinid"] = $vjoinid;
00206 $this->vars[$name]["vfield"] = $vfield;
00207 }
00208
00209
00215 function hide($name, $value = null) {
00216 if (!isset($this->vars[$name]))
00217 die("unknown field $name");
00218
00219 if (!empty($value))
00220 $this->vars[$name]["value"] = $value;
00221
00222 $this->vars[$name]["edit"] = false;
00223 $this->vars[$name]["show"] = false;
00224 }
00225
00226
00230 function hide_id() {
00231 $this->idsum = false;
00232 }
00233
00234
00240 function lock($name, $value = null) {
00241 if (!isset($this->vars[$name]))
00242 die("unknown field $name");
00243
00244 if (!empty($value))
00245 $this->vars[$name]["value"] = $value;
00246
00247 $this->vars[$name]["edit"] = false;
00248 }
00249
00254 function from_db($id) {
00255 $sql = $this->make_select(false,$id);
00256 $res = $this->dbh->query($sql);
00257
00258 if ($myrow = mysql_fetch_assoc($res)) {
00259 $this->id = $id;
00260 foreach ($this->vars as $key => $val) {
00261 $this->vars[$key]['value'] = $myrow[$key];
00262 }
00263 reset($this->vars);
00264 return true;
00265 } else {
00266 return false;
00267 }
00268 }
00269
00270
00273 function from_request() {
00274 if (isset($_REQUEST[$this->prefix.'id']))
00275 $this->id = clean_request($this->prefix.'id');
00276
00277 foreach ($this->vars as $key => $val) {
00278
00279 if ($val['edit'])
00280 $this->vars[$key]['value'] = clean_request($this->prefix.$key);
00281
00282
00283 switch ($val['type']) {
00284 case "set":
00285 if ( is_array($this->vars[$key]['value']) )
00286 $this->vars[$key]['value'] = implode(",",$this->vars[$key]['value']);
00287 break;
00288 case "timestamp":
00289 $this->vars[$key]['value'] = mktime($this->vars[$key]['value']);
00290 break;
00291 }
00292 }
00293 reset($this->vars);
00294 }
00295
00296
00299 function to_db() {
00300 $varlst = new flagset();
00301 foreach ($this->vars as $key => $val) {
00302 # we only want fields from our own table that are either editable or new
00303 if (($val['table'] == $this->table) && ($val['edit'] || !isset($this->id))) {
00304 switch ($val['type']) {
00305 case "password":
00306 if ($val['value'])
00307 $varlst->addflag("$key='".md5($val['value'])."'");
00308 break;
00309 default:
00310 $varlst->addflag("$key='{$val['value']}'");
00311 }
00312 }
00313 }
00314 reset($this->vars);
00315
00316 if (isset($this->id)) {
00317 $sql = "update {$this->table} set {$varlst->value} where {$this->idfield}='{$this->id}'";
00318 if ($this->wheres)
00319 $sql .= " AND " . join(" AND ", $this->wheres);
00320 } else {
00321 if (!$this->autoinc && !$this->idedit) {
00322 list($this->id) = mysql_fetch_row($this->dbh->query("select MAX({$this->idfield})+1 from {$this->table}"));
00323 $varlst->addflag("{$this->idfield}='{$this->id}'");
00324 }
00325 $sql = "insert into {$this->table} set {$varlst->value}";
00326 }
00327 $this->dbh->query($sql);
00328
00329
00330 if ($this->idedit) {
00331 $this->id = $this->vars[$this->idfield]['value'];
00332 } else if ($this->autoinc && !isset($this->id)) {
00333 $this->id = $this->dbh->insert_id();
00334 }
00335 }
00336
00337
00342 function make_join_flag($val) {
00343 if ($val['table'] == $this->table) {
00344
00345 return "";
00346 } else {
00347
00348 $tbl_key = $val['table'];
00349 $tbl_val = $this->jtables[$tbl_key];
00350 $flg = "left join $tbl_key on {$this->table}.{$this->idfield}={$tbl_key}.{$tbl_val['joinid']}";
00351 if ($tbl_val['joinextra'])
00352 $flg .= " and {$tbl_val['joinextra']}";
00353 return $flg;
00354 }
00355 }
00356
00357
00364 function make_select($list,&$num) {
00365 if ($list) {
00366 $varlst = new flagset("{$this->table}.{$this->idfield}");
00367 $orderby = "";
00368 $num = $this->idsum ? 1 : 0;
00369 } else {
00370 $varlst = new flagset();
00371 }
00372
00373 $joinlst = new flagset();
00374
00375 foreach ($this->vars as $key => $val) {
00376
00377
00378 if (!$list || $val['sum']) {
00379
00380 if ($val['type'] == "timestamp")
00381 $varlst->addflag("UNIX_TIMESTAMP({$val['table']}.{$val['field']}) as $key");
00382 else
00383 $varlst->addflag("{$val['table']}.{$val['field']} as $key");
00384
00385
00386 if ($flag = $this->make_join_flag($val))
00387 $joinlst->addflag($flag);
00388
00389
00390 if ($list) {
00391 if (!$orderby) $orderby = "order by $key";
00392 $num++;
00393 }
00394 }
00395 }
00396
00397 reset($this->vars);
00398
00399 $sql = "select {$varlst->value} from {$this->table} {$joinlst->value}";
00400
00401 # if we are in edit mode, add a WHERE condition
00402 if (!$list)
00403 $this->add_where_condition("{$this->table}.{$this->idfield}='$num'");
00404
00405 # sum up all the WHERE conditions
00406 if ($this->wheres)
00407 $sql .= " where " . join(" AND ", $this->wheres);
00408
00409 # add order by clause
00410 if ($list)
00411 $sql .= " $orderby";
00412
00413 return $sql;
00414 }
00415
00416
00422 function set_maxrows($maxrows)
00423 {
00424
00425 if ($maxrows < 0) {
00426 trigger_error("You cannot pass a negative number ($maxrows) to set_maxrows!");
00427 return;
00428 }
00429
00430 $this->maxrows = $maxrows;
00431 }
00432
00440 function run(&$page,$outputvar='',$template='') {
00441 global $globals;
00442
00443 $action = clean_request('action');
00444 $page->assign('table',$this->table);
00445
00446 switch($action) {
00447 case "edit":
00448
00449 if ($this->readonly) die("Sorry, this table is read-only.");
00450
00451
00452 if (clean_request("{$this->prefix}id") != '') {
00453 $this->from_db(clean_request("{$this->prefix}id"));
00454 $page->assign('id',$this->id);
00455 }
00456
00457
00458 #foreach ($this->vars as $key => $val) {
00459 #if (!$val['edit'])
00460 # unset($this->vars[$key]);
00461 #}
00462 reset($this->vars);
00463
00464 $page->assign('doedit',true);
00465 break;
00466 case "update":
00467
00468 if ($this->readonly) die("Sorry, this table is read-only.");
00469
00470 $this->from_request();
00471 $this->to_db();
00472 break;
00473 case "del":
00474
00475 if ($this->readonly) die("Sorry, this table is read-only.");
00476
00477 $this->delete_db(clean_request("{$this->prefix}id"));
00478 break;
00479 }
00480
00481
00482 if ($action != "edit") {
00483 $ncols = 0;
00484 $sql = $this->make_select(true,$ncols);
00485 $res = $this->dbh->query($sql);
00486 $page->assign('ncols',$ncols);
00487
00488
00489 $p_total = mysql_num_rows($res);
00490 $p_start = isset($_REQUEST['start']) ? $_REQUEST['start'] : 0;
00491 $p_stop = $this->maxrows ? min($p_total, $p_start + $this->maxrows) : $p_total;
00492 $counter = 0;
00493
00494 while (($counter < $p_stop) and ($myarr = mysql_fetch_assoc($res))) {
00495 if ($counter >= $p_start) {
00496 $actions = array();
00497 foreach ($this->actions as $myaction) {
00498 $url = $myaction['url'];
00499 foreach ($myarr as $key=>$val)
00500 $url = str_replace("%$key%", $val, $url);
00501
00502 array_push($actions, array($myaction['text'],$url));
00503 }
00504 $page->append('rows', array($myarr[$this->idfield], $myarr, $actions) );
00505 }
00506 $counter++;
00507 }
00508 mysql_free_result($res);
00509
00510
00511 $page->assign('p_prev', $p_start ? max($p_start - $this->maxrows, 0) : -1);
00512 $page->assign('p_next', ($p_stop < $p_total) ? $p_stop : - 1 );
00513 $page->assign('p_total', $p_total);
00514
00515 }
00516
00517 $page->assign('vars',$this->vars);
00518 $page->assign('prefix',$this->prefix);
00519 $page->assign('idfield',$this->idfield);
00520 $page->assign('idsum',$this->idsum);
00521 $page->assign('readonly',$this->readonly);
00522 if ($this->readonly && ($this->actions == array()))
00523 $page->assign('hideactions', 1);
00524 $page->assign('table_class', $this->table_class);
00525 $page->assign('table_style', $this->table_style);
00526
00527
00528 $page->assign('msg_previous_page', __("previous page"));
00529 $page->assign('msg_next_page', __("next page"));
00530 $page->assign('msg_id', __("id"));
00531 $page->assign('msg_action', __("action"));
00532 $page->assign('msg_create', __("create"));
00533 $page->assign('msg_delete', __("delete"));
00534 $page->assign('msg_edit', __("edit"));
00535 $page->assign('msg_new_entry', __("new entry"));
00536 $page->assign('msg_existing_entry', __("existing entry"));
00537 $page->assign('msg_no_change', __("(blank = no change)"));
00538 $page->assign('msg_back', __("back"));
00539 $page->assign('msg_confirm_delete',
00540 __("You are about to delete this entry. Do you want to proceed?"));
00541 $page->assign('msg_submit', __("Submit"));
00542
00543
00544 if (!empty($outputvar)) {
00545 if (empty($template))
00546 $template = $globals->libroot."/templates/table-editor.tpl";
00547 $page->assign($outputvar, $page->fetch($template));
00548 }
00549 }
00550
00551 }
00552
00553 ?>